使用字符串在dplyr(或基数R)中每行选择列

sha*_*roz 5 r dplyr

我有一个填充其他列名称的列.我想获取每个列名称中的值.

# three columns with values and one "key" column
library(dplyr)
data = data.frame(
  x = runif(10),
  y = runif(10),
  z = runif(10),
  key = sample(c('x', 'y', 'z'), 10, replace=TRUE)
)

# now get the value named in 'key'
data = data %>% mutate(value = VALUE_AT_COLUMN(key))
Run Code Online (Sandbox Code Playgroud)

我很确定答案与mutate的懒惰eval版本有关,但我不能为我的生活弄明白.

任何帮助,将不胜感激.

akr*_*run 6

我们可以试试data.table.将'data.frame'转换为'data.table'(setDT(data)),按行序列分组,我们用于.SD对'key'指定的列进行子集化.

 library(data.table)
 setDT(data)[,  .SD[, key[[1L]], with=FALSE] ,1:nrow(data)]
Run Code Online (Sandbox Code Playgroud)

或者另一种选择是get在按行序列分组后将'key'转换为characterclass(因为它factor),如前一种情况.

 setDT(data)[, get(as.character(key)), 1:nrow(data)]
Run Code Online (Sandbox Code Playgroud)

这是一个选项 do

 library(dplyr)
 data %>% 
    group_by(rn = row_number()) %>%
    do(data.frame(., value= .[[.$key]]))
Run Code Online (Sandbox Code Playgroud)

  • 你可以发贴这个作为答案吗? (2认同)

Sam*_*son 5

这是一个Base R解决方案:

data$value = diag(as.matrix(data[,data$key]))
Run Code Online (Sandbox Code Playgroud)

  • 不!可能有更多内存有效的基本方法,但如果你想要性能,那么你应该看看`data.table`或`dplyr`.如果您不想加载更多的软件包并且数据量不大,那么这将有效. (2认同)

Aru*_*run 5

对于内存高效且快速的解决方案,您应该通过执行连接来更新原始data.table,如下所示:

data[.(key2 = unique(key)), val := get(key2), on=c(key="key2"), by=.EACHI][]
Run Code Online (Sandbox Code Playgroud)

对于每个key2匹配的行data$key都是计算出来的.这些行使用包含在其中的列中的值进行更新key2.例如,key2="x"与行匹配1,2,6,8,10.相应的值data$xdata$x[c(1,2,6,8,10)].by=.EACHI确保get(key2)为每个值执行表达式key2.

由于此操作仅在唯一值上执行,因此应比在行中执行操作快得多.由于data.table是通过引用更新的,因此它应该具有很高的内存效率(这也有助于提高速度).