2017-04-10 129 views
3

如何用Tidyverse替换R中某个子集的值?使用Tidyverse替换R中的子集

使用cars数据作为一个例子,如果我想改变所有超过30到0下的speed,我可以使用下面的命令:

cars[cars["speed"] < 30,] <- 0 

随着Tidyverse,可以产生相同的子集更可读命令:

cars %>% filter(speed < 30) %>% mutate(speed =0) 

然而,这是改变数据的子集,我们从cars中取出,观察不值内cars

我可能错过了一些明显的东西,但是有没有一种直观的方式可以用Tidyverse做同样的事情?虽然cars[cars["speed"] < 30,] <- 0在大多数情况下都能正常工作,但如果有5个以上的条件可以满足,它变得非常不便。

+0

我想这可能是当你不SHLD试图让一切“整洁”的情况下。 'replace'就是'x [list] < - values',这几乎就是你所做的,而且它是 - IMO - 就像可读性和抽象性一样。 – hrbrmstr

回答

5

您可以使用replace功能:

cars %>% mutate(speed = replace(speed, speed < 30, 0)) 

ifelse条件也将工作:

cars %>% mutate(speed = ifelse(speed < 30, 0, speed)) 

我测试了这一个一百万行数据帧和replace在约一跑 - 时间ifelse

library(microbenchmark) 

set.seed(2) 
dat = data.frame(x=runif(1e6, 0, 1000), y=runif(1e6, 0, 1000)) 

microbenchmark(
    replace=dat %>% mutate(x=replace(x, x<200, 0)), 
    ifelse=dat %>% mutate(x=ifelse(x<200, 0, x)), 
    times=20 
) 
Unit: milliseconds 
    expr  min  lq  mean median  uq  max neval cld 
replace 9.553371 10.32223 13.74662 10.99693 17.41123 21.98736 20 a 
    ifelse 85.785029 93.09105 196.69298 98.71720 320.97928 333.57374 20 b