在行级别进行子设置,但值必须是列名称

时间:2015-01-14 20:22:11

标签: r

想象一下数据框:

set.seed(1234)
data<-data.frame(id = sample(letters, 26, replace = FALSE), 
                         a = sample(1:10,26,replace=T),
                         b = sample(1:10,26,replace=T), 
                         c = sample(1:10,26,replace=T))

我希望为每个id保留最大值所在的列名。

我要查找的结果是尺寸为26 x 2的数据框,其中id的列和largest_value_var的列。 largest_value_var将包含abc

到目前为止,我已经能够使用以下方法提取与最大值相关联的变量名称:

apply(data[,-1], 1, function(x) c(names(x))[which.max(x)])

但我似乎无法将我想要的结果变成数据帧...... 任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:7)

您可以使用max.col()轻松完成此操作。设置ties.method = "first"(感谢akrun),我们将在平局的情况下得到第一列。这是一个数据表方法:

library(data.table)
setDT(data)[, names(.SD)[max.col(.SD, "first")], by = id]

更新:在基础R中实施此方法似乎更有效,可能是因为as.matrix()中的max.col()转换。所以这是在基地完成它的一种方法。

cbind(data[1], largest = names(data)[-1][max.col(data[-1], "first")])

感谢Ananda Mahto指出效率差异。

答案 1 :(得分:4)

我喜欢@ Richard使用max.col,但我想到的第一件事就是真正将数据变成一个整洁的&#34;先形成,然后进行你想要的子集化应该很容易:

library(reshape2)
library(data.table)
melt(as.data.table(data), id.vars = "id")[, variable[which.max(value)], by = id]
#     id V1
#  1:  c  b
#  2:  p  a
#  3:  o  c
#  4:  x  b
#  5:  s  a
## SNIP ###
# 21:  g  a
# 22:  f  b
# 23:  t  a
# 24:  y  a
# 25:  w  b
# 26:  v  a
#     id V1

答案 2 :(得分:3)

为了将apply()调用的结果放入数据框,您可以执行

df <- data.frame(id=data$id,
             largest_value_var=apply(data[,-1], 1, function(x) names(x)[which.max(x)]))

请注意,c(names(x))names(x)相同,因此我省略了c()