一个 data.table
的解决方案。
library(data.table)
DT <- as.data.table(df)
DT[,.SD[which.min(v1)], by = f]
或者更高效的方式
DT[DT[,.I[which.min(v1)],by=f][['V1']]]
一些基准测试
f <- rep(letters[1:20],100000)
v1 <- rnorm(20*100000)
v2 <- 1:(20*100000)
df <- data.frame(f,v1,v2)
DT <- as.data.table(df)
f1<-function(){df2<-df[order(df$f,df$v1),]
df2[!duplicated(df2$f),]}
f2<-function(){df2<-df[order(df$v1),]
df2[!duplicated(df2$f),]}
f3<-function(){df[ df$v1 == ave(df$v1, df$f, FUN=min), ]}
f4 <- function(){DT[,.SD[which.min(v1)], by = f]}
f5 <- function(){DT[DT[,.I[which.min(v1)],by=f][['V1']]]}
library(microbenchmark)
microbenchmark(f1(),f2(),f3(),f4(), f5(),times = 5)
.I
方法是获胜者(FR #2330希望在实现时也能像.SD
方法一样快速而优雅)。
?ave
:ave(x,factor1,factor2,factor3,factor4,...,FUN=min) - Joris Meys