2015-01-14 22 views
5

想象一下,一个数据帧:子集行级,但值必须是列名

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_varlargest_value_var将包含a,bc

到目前为止,我已经能够提取与最大值使用此关联的变量名:

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

但我似乎无法完全得到我想要到一个结果dataframe ... 任何帮助表示赞赏。

回答

7

你可以用max.col()很容易地做到这一点。设置ties.method = "first"(感谢akrun),我们将在领带的情况下获得第一列。这里有一个数据表的方法:

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

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

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

感谢Ananda Mahto指出的效率差异。

4

我喜欢@理查德的使用max.col,而是来到了我的脑海里的第一件事是把数据实际上进入一个“整洁”的形式第一,之后做你想做应该是容易的子集:

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 
+0

我比你喜欢你的评论解决方案。等等...你删除了它? –

+1

@BonddedDust,no。自从他在我面前想到'max.col'后,我把它交给了理查德。哦,并感谢您的其他评论今天:-) – A5C1D2H2I1M1N2O1R2T1

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()

+0

@RichardScriven,实际上没有在这种情况下需要分组。 – A5C1D2H2I1M1N2O1R2T1

相关问题