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帮助文件,并认为可能有使用扫描的解决方案?任何帮助赞赏。
答案 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"