为了账号安全,请及时绑定邮箱和手机立即绑定

仅保留每个因子水平的最小值

仅保留每个因子水平的最小值

蛊毒传说 2019-10-11 14:44:12
我遇到了困扰我一段时间的问题……希望这里的任何人都可以帮助我。我得到以下数据框f <- c('a','a','b','b','b','c','d','d','d','d')v1 <- c(1.3,10,2,10,10,1.1,10,3.1,10,10)v2 <- c(1:10)df <- data.frame(f,v1,v2)f是一个因素;v1和v2是值。对于f的每个级别,我只想保留一行:在该因子级别中v1值最低的那一行。f   v1  v2a   1.3 1b   2   3c   1.1 6d   3.1 8我尝试了聚合,ddply,by,tapply等各种方法,但是似乎没有任何效果。如有任何建议,我将非常感谢。
查看完整描述

3 回答

?
潇潇雨雨

TA贡献1833条经验 获得超4个赞

使用DWin的解决方案,tapply可以避免使用ave。


df[ df$v1 == ave(df$v1, df$f, FUN=min), ]

如下所示,这又可以提高速度。请注意,这也取决于级别数。我注意到ave,尽管它是R中更强大的功能之一,但我经常忘记它。


f <- rep(letters[1:20],10000)

v1 <- rnorm(20*10000)

v2 <- 1:(20*10000)

df <- data.frame(f,v1,v2)


> system.time(df[ df$v1 == ave(df$v1, df$f, FUN=min), ])

   user  system elapsed 

   0.05    0.00    0.05 


> system.time(df[ df$v1 %in% tapply(df$v1, df$f, min), ])

   user  system elapsed 

   0.25    0.03    0.29 


> system.time(lapply(split(df, df$f), FUN = function(x) {

+             vec <- which(x[3] == min(x[3]))

+             return(x[vec, ])

+         })

+  .... [TRUNCATED] 

   user  system elapsed 

   0.56    0.00    0.58 


> system.time(df[tapply(1:nrow(df),df$f,function(i) i[which.min(df$v1[i])]),]

+ )

   user  system elapsed 

   0.17    0.00    0.19 


> system.time( ddply(df, .var = "f", .fun = function(x) {

+     return(subset(x, v1 %in% min(v1)))

+     }

+ )

+ )

   user  system elapsed 

   0.28    0.00    0.28 


查看完整回答
反对 回复 2019-10-11
  • 3 回答
  • 0 关注
  • 449 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信