2017-10-20 30 views
1

我非常努力地找到答案,如果它是重複的,我很抱歉。有條件地將列中的值替換爲另一列中的值使用dplyr

我會製作一些虛擬數據來解釋我的問題。

tibble(a=c(0.1, 0.2, 0.3), sample1 = c(0, 1, 1), sample2 = c(1, 1, 0)) 

# A tibble: 3 x 3 
     a sample1 sample2 
<dbl> <dbl> <dbl> 
1 0.1  0  1 
2 0.2  1  1 
3 0.3  1  0 

如何我有條件地更改列SAMPLE1SAMPLE2所以,如果他們都等於一個,他們承擔的一個值的值。

產生的tibble應該是這樣的:

# A tibble: 3 x 3 
     a sample1 sample2 
<dbl> <dbl> <dbl> 
1 0.1  0  0.1 
2 0.2  0.2  0.2 
3 0.3  0.3  0 

理想我不想爲每個樣品列做到這一點(我有> 100樣本列),所以地遍歷列會更好(雖然我知道循環是魔鬼)。

感謝您的幫助!

回答

1

您可以使用mutate_atifelse

df %>% mutate_at(vars(starts_with('sample')), funs(ifelse(. == 1, a, .))) 

# A tibble: 3 x 3 
#  a sample1 sample2 
# <dbl> <dbl> <dbl> 
#1 0.1  0.0  0.1 
#2 0.2  0.2  0.2 
#3 0.3  0.3  0.0 

vars(starts_with('sample'))匹配以samplemutate_at開始的所有列應用功能funs(ifelse(. == 1, a, .))到每一列; .代表此處匹配的列。


如果你確信所有的樣品列僅包含10,可以縮短爲:使用which()

df %>% mutate_at(vars(starts_with('sample')), funs(. * a)) 

# A tibble: 3 x 3 
#  a sample1 sample2 
# <dbl> <dbl> <dbl> 
#1 0.1  0.0  0.1 
#2 0.2  0.2  0.2 
#3 0.3  0.3  0.0 
+0

人.. 。我嘗試了一段時間玩mutate_at,但是我的錯誤是使用replace()而不是ifelse()。這工作完美...謝謝! – Ryan

+0

'replace'是我的第一個想法。但它要求條件和替換具有相同的長度或可循環使用,這不像'ifelse'這樣方便。 – Psidom

-1

非dplyr解決方案:

> t=tibble(a=c(0.1, 0.2, 0.3), sample1 = c(0, 1, 1), sample2 = c(1, 1, 0)) 

> whichRows=which(t$sample1==t$sample2) 

> t[whichRows,c('sample1','sample2')]<-t[whichRows,'a'] 

> t 
# A tibble: 3 x 3 
     a sample1 sample2 
    <dbl> <dbl> <dbl> 
1 0.1  0.0  1.0 
2 0.2  0.2  0.2 
3 0.3  1.0  0.0 
相關問題