2017-07-16 57 views
3

我不知道是否有一個dplyr相當於dplyr相當於DF [DF == X] < - Ÿ

df <- data.frame(A=1:5,B=2:6,C=-1:3) 
df[df==2] <- 10 

我在尋找

df %>% <??> 

也就是說,聲明即與其他dplyr動詞鏈接

+1

不是我所知道的,但你找到它了嗎?這似乎是在https://stackoverflow.com/questions/34096162/dplyr-mutate-replace-on-a-subset-of-rows或https://stackoverflow.com/questions/23078891/how-to-更新價值與dplyr –

+0

@DavidArenburg我總是試圖看看。並不意味着我總是成功。感謝您的鏈接...可能的答案是軟* NO *,考慮到第一個鏈接寫了一個函數來做到這一點。第二個鏈接只改變了一列,但看起來像一個很有前途的開始...... – CPak

+0

雖然我不是最新的'dplyr'。它似乎每天都在發展。更不用說它是'tidyverse'的一部分,所以你可能需要通過約1K的功能來確定。另外,也許'magrittr'有東西可以提供。關於第二個環節,這只是標準的基礎'ifelse',同樣喜歡在他們使用'\'[<第一個環節 - data.frame \''和'replace' - 所有基礎R東西臥底(沒有理由IMO )。 –

回答

7

1)替換試試這個。它只需要magrittr雖然dplyr進口magrittr相關的部分,因此將與dplyr工作太:

df %>% replace(. == 2, 10) 

,並提供:

A B C 
1 1 10 -1 
2 10 3 0 
3 3 4 1 
4 4 5 10 
5 5 6 3 

1A)覆蓋注意的是,以上的非破壞性如此如果您想更新df,那麼你將需要將其分配回:

df <- df %>% replace(. == 2, 10) 

df %>% replace(. == 2, 10) -> df 

或使用magrittr %<>%運營商消除引用df兩次:

df %<>% replace(. == 2, 10) 

2)算術這也將工作:

df %>% { 10 * (. == 2) + . * (. != 2) } 
+0

即使整潔...感謝 – CPak

+0

所以它只是一個像其他環節基礎R解決方案。我沒有看到任何dplyr在這裏相關(這是關於的問題)。無論我怎麼看它是任何比'替換(DF,DF == 2,10)更好'或'DF [DF = = 2] < - 10' –

+2

我指出很清楚,它只是需要magrittr還要注意的是, %<>%解決方案只需要一個基準的df與2的引用。我認爲這個問題的意圖是如何做到這一點。 –

2

的OP的問題是關於如何使用dplyr代替值,並且由G.Gotothendieck解決。但我很好奇,基於dplyrdata.table和base R的不同方法之間的性能差異如何。於是我設計並執行了以下基準測試。

# Load package 
library(dplyr) 
library(data.table) 
library(microbenchmark) 

# Create example data frame 
df <- data.frame(A = 1:5, B = 2:6, C = -1:3) 
# Convert to data.table 
dt <- as.data.table(df) 

# Method 1: Use mutate_all and ifelse 
F1 = function(df){df %>% mutate_all(funs(ifelse(. == 2, 10, .)))} 
# Method 2: Use mutate_all and replace 
F2 = function(df){df %>% mutate_all(funs(replace(., . == 2, 10)))} 
# Method 3: Use replace 
F3 = function(df){df %>% replace(. == 2, 10)} 
# Method 4: Base R data frame assignment 
F4 = function(df){ 
    df[df == 2] <- 10 
    return(df) 
} 

# Benchmarking 
microbenchmark(
    M1 = F1(df), 
    M2 = F2(df), 
    M3 = F3(df), 
    M4 = F4(df), 
    # Same as M4, but use data.table object as input 
    M5 = F4(dt) 
) 

Unit: microseconds 
expr  min   lq  mean  median   uq  max neval 
    M1 8634.974 13028.7975 17224.4669 14907.3735 19496.5275 79750.182 100 
    M2 8925.565 12626.2675 16698.7412 15551.7410 18658.1125 35468.760 100 
    M3 282.252 391.6240 591.2534 553.5980 647.8965 3290.797 100 
    M4 163.578 252.1025 423.7627 349.6080 420.8125 5415.382 100 
    M5 228.367 333.2495 596.1735 440.3775 555.5230 7506.609 100 

結果表明,與mutata_allifelseM1)或replaceM2)比其他方法慢得多。使用replace與管道(M3)速度較快,但仍比基準R(M4)慢一點。將data.frame轉換爲data.table,然後應用分配替換(M5)不會比M4更快。

所以,我認爲在這種情況下,沒有特別的需要使用dplyr函數,因爲它不比基準R方法(M4)更快。也不需要將data.frame轉換爲data.table如果需要管道操作。我們可以使用管道replaceM3)。或者,我們可以定義一個函數,如F4,並將其放入管道操作中。

+0

感謝您的配合。很高興知道他們如何在表現中積累。根據我的經驗,非答案答案*有爭議*,但我認爲它值得一看。 – CPak

+1

成語一致性通常勝過我在現實世界中 – hrbrmstr

+0

@hrbrmstr我同意豐富的經驗,「微秒性能」的好處。成語一致性有助於代碼可讀性。對於小數據幀,習語一致性比「微秒性能」更重要。但是,如果有很多數據幀或大數據幀,「微秒性能」可能很重要。當我說「在這種情況下」時,我不僅僅是指這個小數據框,而是這種一般操作。 – www