在R中查找最大值的索引

22

我有一个名为surge的数据框:

MeshID    StormID Rate Surge Wind
1         1412 1.0000E-01   0.01 0.0
2         1412 1.0000E-01   0.03 0.0
3         1412 1.0000E-01   0.09 0.0
4         1412 1.0000E-01   0.12 0.0
5         1412 1.0000E-01   0.02 0.0
6         1412 1.0000E-01   0.02 0.0
7         1412 1.0000E-01   0.07 0.0
1         1413 1.0000E-01   0.06 0.0
2         1413 1.0000E-01   0.02 0.0
3         1413 1.0000E-01   0.05 0.0

我使用下面的代码来查找每个风暴浪涌的最大值:

MaxSurge <- data.frame(tapply(surge[,4], surge[,2], max))

它返回:

1412 0.12
1413 0.06

这很棒,但我还想在涌浪达到最高点时包括MeshID的值。我知道我可能可以使用which.max函数,但我不太清楚如何实现。我是R编程的新手。


3
+1 对于一个良好提出的问题。它包含了一切,1)数据,2)你尝试过的事情,3)它如何没有完全满足你的需求。 - Joshua Ulrich
2
MaxSurge[which.max(MaxSurge[,4]),1] 是一种简单粗暴的方法。 - Carl Witthoft
4个回答

14

还有一个data.table解决方案,使代码更加优雅

library(data.table)
surge <- as.data.table(surge)
surge[, .SD[which.max(surge)], by = StormID]

13

这里提供另一种data.table的解决方案,但不依赖于.SD(因此速度快10倍)

surge[,grp.ranks:=rank(-1*surge,ties.method='min'),by=StormID]
surge[grp.ranks==1,]

3
非常好!当添加.I后,这会变得更加容易(我希望它甚至更快):surge[surge[, .I[which.max(surge)], by=StormID, drop=TRUE]]。虽然有点丑陋,但我们可以自动优化.SD方法来在幕后执行此操作,以保留mnel答案的优雅性。所以只是要注意,正如您所说,如果可能应该避免使用.SD,因为它会创建整个子集,这可能是不必要的。但是这在未来有希望改变。将所有内容放在 [...] 中的原因之一是 data.table 可以在未来优化这些内容。 - Matt Dowle

7
如果你的数据点最多有2个,那么which.max只会指向第一个。更完整的解决方案涉及到rank:
# data with a tie for max  
surge <- data.frame(MeshID=c(1:7,1:4),StormID=c(rep(1412,7),
rep(1413,4)),Surge=c(0.01,0.03,0.09,0.12,0.02,0.02,0.07,0.06,0.02,0.05,0.06))

# compute ranks  
surge$rank <- ave(-surge$Surge,surge$StormID,FUN=function(x) rank(x,ties.method="min"))
# subset on the rank  
subset(surge,rank==1)
   MeshID StormID Surge rank
4       4    1412  0.12    1
8       1    1413  0.06    1
11      4    1413  0.06    1

这个很好用 - 我担心会出现多个最大值。如果我只关心浪涌> .10的情况怎么办? - kimmyjo221
@user1716877 subset(surge,Surge>0.1) @user1716877 subset(surge,Surge>0.1) - James

6
这里有一个plyr解决方案,仅仅是因为如果我不说的话,某些人会这么说...
R> ddply(surge, "StormID", function(x) x[which.max(x$Surge),])
  MeshID StormID Rate Surge Wind
1      4    1412  0.1  0.12    0
2      1    1413  0.1  0.06    0

这两种方法似乎给出了不同的结果。ddply版本有效,因为在函数内部你正在索引x的子集。在tapply版本中,which.max返回子集中最大值的索引,但是使用它来索引整个x - seancarmody
我能再问一个问题吗?如果我想要计算特定stormID中最大值重复出现的次数,我该怎么做?目前只是选择第一个Surge为最大值的MeshID实例,对吗?如果最大值出现超过一次怎么办?谢谢。 - kimmyjo221
完美!抱歉,还有一个问题。如果我只对那些浪涌 > .10 的情况感兴趣怎么办? - kimmyjo221

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接