返回包含数据框中所有变量的最大值的列

时间:2012-01-20 13:02:04

标签: r dataframe

zone_id=1:6
v1=c(12,22,31,12,5,17)
v2=c(15,22,28,16,18,21)
v3=c(18,10,14,9,10,17)
v4=c(20,3,2,5,12,21)
mydata=data.frame(zone_id,v1,v2,v3,v4)

我有一个数据框,可以使用上面的代码制作粗略的模型。它由与地理区域相关的数据行组成。我有变量(在这个例子中有4个,但在我的实际数据集中有69个),它们包含在这些区域中观察的整数。 对于每个zone_id,我想识别从V1到V4的变量,其中包含最大值。如果存在平局,我想返回包含绑定最大值的每个变量的名称。因此对于区域1,我想要返回V4,对于区域2,我想要返回V1和V2,依此类推。

我是R的新手,并且无法通过此获得一垒。我已经探索了R帮助文件,并认为可能有使用扫描的解决方案?任何帮助赞赏。

2 个答案:

答案 0 :(得分:3)

您可以在此处使用which(x == max(x))惯用法,并使用apply()针对每一行执行此操作:

apply(mydata[, -1], 1, function(x) which(x == max(x)))

给出:

> apply(mydata[, -1], 1, function(x) which(x == max(x)))
[[1]]
v4 
 4 

[[2]]
v1 v2 
 1  2 

[[3]]
v1 
 1 

[[4]]
v2 
 2 

[[5]]
v2 
 2 

[[6]]
v2 v4 
 2  4

该列表包含最大变量索引的向量,并且可以使用names()提取这些向量的名称以提供实际变量ID:

> out <- apply(mydata[, -1], 1,  function(x) which(x == max(x)))
> names(out[[2]])
[1] "v1" "v2"
> lapply(out, names)
[[1]]
[1] "v4"

[[2]]
[1] "v1" "v2"

[[3]]
[1] "v1"

[[4]]
[1] "v2"

[[5]]
[1] "v2"

[[6]]
[1] "v2" "v4"

如果您的数据可能包含NA,那么我们需要更加聪明,例如。

apply(mydata[, -1], 1, 
      function(x, na.rm = FALSE)
          which(x == max(x, na.rm = na.rm)),
      na.rm = TRUE)

其中我们可以传入是否忽略NA

答案 1 :(得分:2)

一种方法是使用rank。请注意数据前的减号作为默认排序是低 - >高

x <- apply(-mydata[,-1],1,rank,ties.method="min")
x
   [,1] [,2] [,3] [,4] [,5] [,6]
v1    4    1    1    2    4    3
v2    3    1    2    1    1    1
v3    2    3    3    3    3    3
v4    1    4    4    4    2    1

您可以使用sapply提取名称:

sapply(mydata$zone_id,function(y) rownames(x)[x[,y]==1])
[[1]]
[1] "v4"

[[2]]
[1] "v1" "v2"

[[3]]
[1] "v1"

[[4]]
[1] "v2"

[[5]]
[1] "v2"

[[6]]
[1] "v2" "v4"