我的列中填充了其他列名。我希望得到每个列名的值。
# 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))
我很确定答案与mutate的懒惰eval版本有关,但我不能为我的生活弄明白。
任何帮助都将不胜感激。
答案 0 :(得分:6)
我们可以尝试data.table
。将'data.frame'转换为'data.table'(setDT(data)
),按行序列分组,我们使用.SD
对'key'指定的列进行子集化。
library(data.table)
setDT(data)[, .SD[, key[[1L]], with=FALSE] ,1:nrow(data)]
或者,在按照前一种情况按行序列分组后,将“密钥”转换为get
类(因为它character
)后,其他选项为factor
。
setDT(data)[, get(as.character(key)), 1:nrow(data)]
以下是do
library(dplyr)
data %>%
group_by(rn = row_number()) %>%
do(data.frame(., value= .[[.$key]]))
答案 1 :(得分:5)
这是Base R解决方案:
data$value = diag(as.matrix(data[,data$key]))
答案 2 :(得分:5)
对于内存效率和快速解决方案,您应该通过执行连接来更新原始data.table,如下所示:
data[.(key2 = unique(key)), val := get(key2), on=c(key="key2"), by=.EACHI][]
对于每个key2
,计算data$key
中的匹配行。这些行将使用key2
中包含的列中的值进行更新。例如,key2="x"
与行1,2,6,8,10
匹配。 data$x
的相应值为data$x[c(1,2,6,8,10)]
。 by=.EACHI
确保为get(key2)
的每个值执行表达式key2
。
由于此操作仅在唯一值上执行,因此应比在行中执行操作快得多。由于data.table是通过引用更新的,因此它应该具有很高的内存效率(这也有助于提高速度)。
答案 3 :(得分:4)
这肯定感觉应该有一个基本R解决方案,但我能做的最好的是tidyr
,首先将数据转换为宽格式,然后过滤那些与所需匹配的观察键。
data %>%
add_rownames("index") %>%
gather(var, value, -index, -key) %>%
filter(key == var)
基本的R解决方案几乎可以工作:
data[cbind(seq_along(data$key), data$key)]
对于给出的数据,它确实有效,但因为它使用矩阵,所以它有两个严重的问题。一个因素的顺序很重要,因为它只是强迫它,并按因子级别而不是列名称选择列。另一个是结果输出是character
,而不是numeric
,因为在转换为矩阵时,由于character
列而选择了key
类型。关键问题是
data.frame
类比
当用'''单个参数'i'索引数组时,可以是一个矩阵,其列数与'x'的维数相同;结果是一个向量,其元素对应于'i'每行中的索引集。
鉴于这些问题,我可能会使用tidyr
解决方案,因为列可变地可选,这意味着它们可能代表同一可观察单元的不同观察结果。