I have the following data frame called 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
I used the following code to find the max value of surge per storm:
MaxSurge <- data.frame(tapply(surge[,4], surge[,2], max))
It returns:
1412 0.12
1413 0.06
This is great, except I'd also like it to include the MeshID
value at the point where the surge is the maximum. I know I can probably use which.max
, but I can't quite figure out how to put this in action. I'm VERY new to R programming.
Similarly we can do the same for finding out the maximum element using the max() function and then find out the index of the maximum element using the index() inbuilt function in python. Note: index() returns the index of the first occurrence in case there are multiple occurrences of an element.
min() Function. which. min() function in R Language is used to return the location of the first minimum value in the Numeric Vector.
max() function in R Language is used to find the maximum element present in an object.
max index(es) is the index for the first max value. If array is multidimensional, max index(es) is an array whose elements are the indexes for the first maximum value in array. min value is of the same data type and structure as the elements in array. min index(es) is the index for the first min value.
And a data.table
solution for coding elegance
library(data.table)
surge <- as.data.table(surge)
surge[, .SD[which.max(surge)], by = StormID]
here is another data.table solution, but not relying on .SD (thus 10x faster)
surge[,grp.ranks:=rank(-1*surge,ties.method='min'),by=StormID]
surge[grp.ranks==1,]
If you have 2 data.points at the maximum, which.max
will only refer to the first one. A more complete solution would involve 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With