2017-04-10 61 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