r - 如何在多列上使用提取并根据输入列名称命名输出列
问题描述
我有以下形式的血压数据数据框:
bpdata <- data.frame(bp1 = c("120/89", "110/70", "121/78"), bp2 = c("130/69", "120/90", "125/72"), bp3 = c("115/90", "112/71", "135/80"))
我想使用以下提取命令,但在全局范围内,即在所有 bp\d 列上
extract(bp1, c("systolic_1","diastolic_1"),"(\\d+)/(\\d+)")
如何捕获列选择中的数字并在列输出名称中使用它?我可以通过创建列名列表然后使用其中一个 apply 系列来解决这个问题,但在我看来,应该有一种更优雅的方式来做到这一点。
有什么建议么?
解决方案
我们可以read.csv
在循环中的多个列上使用 ( Map
) withsep = "/"
和cbind
最后的list
元素do.call
do.call(cbind, Map(function(x, y) read.csv(text= x, sep="/", header = FALSE,
col.names = paste0(c('systolic', 'diastolic'), y)),
unname(bpdata), seq_along(bpdata)))
# systolic1 diastolic1 systolic2 diastolic2 systolic3 diastolic3
#1 120 89 130 69 115 90
#2 110 70 120 90 112 71
#3 121 78 125 72 135 80
或者没有循环,paste
将每行的列转换为单个字符串,然后使用read.csv/read.table
read.csv(text = do.call(paste, c(bpdata, sep="/")),
sep="/", header = FALSE,
col.names = paste0(c('systolic', 'diastolic'),
rep(seq_along(bpdata), each = 2)))
# systolic1 diastolic1 systolic2 diastolic2 systolic3 diastolic3
#1 120 89 130 69 115 90
#2 110 70 120 90 112 71
#3 121 78 125 72 135 80
或使用tidyverse
,类似的选项是unite
将列分成一个 with /
,然后使用extract
或separate
将列拆分为多个列
library(dplyr)
library(tidyr)
library(stringr)
bpdata %>%
unite(bpcols, everything(), sep="/") %>%
separate(bpcols, into = str_c(c('systolic', 'diastolic'),
rep(seq_along(bpdata), each = 2)), convert = TRUE)
# systolic1 diastolic1 systolic2 diastolic2 systolic3 diastolic3
#1 120 89 130 69 115 90
#2 110 70 120 90 112 71
#3 121 78 125 72 135 80
推荐阅读
- regex - 正则表达式在第 n 个特殊字符和字符串之间进行选择
- javascript - 在 chrome 开发工具上访问 iframe 上下文
- angular - 尝试在 Ionic v4 中的模型上提交表单
- arrays - 从数组条目计算特定字段的总和
- javascript - 如何在具有最大字符长度的许多其他字符串中拆分唯一字符串
- javascript - React 没有在我的状态下识别对象
- reporting-services - 如何查询 SSRS 数据驱动订阅明细
- java - Bean 上的@ConditionalOnProperty,必须根据两个条件加载,来自 application.yml 配置文件
- python - Python MySQLdb游标在大量插入时执行不工作
- javascript - 初始化firebase模拟器存储