2016-04-26 45 views
1

我有一些數字數據(value),它被分組(按Tissue)。我想爲每組中出現多次的值添加一個小抖動。dplyr:將抖動添加到組中的重複值

輸入:

df <- structure(list(value = c(1.05155243861439, 
1.05155243861439, 1.05155243861439, 11.9769249796958, 1.05155243861439, 
1.05155243861439, 1.05155243861439, 1.05155243861439, 1.05155243861439 
), Tissue = structure(c(5L, 5L, 5L, 4L, 5L, 3L, 5L, 1L, 1L 
), .Label = c("Brain", "Marrow", "Spleen", "Testes", "Vis"), class = "factor")), .Names = c("value", 
"Tissue"), row.names = c("SM-2", "SM-3", "SM-4", "SM-5", 
"SM-6", "SM-7", "SM-8", "SM-9", "SM-10"), class = "data.frame") 

我嘗試使用group_bymutate,但這增加了相同的抖動於每個重複的元素每組(一種毫無意義的,是嗎?)。

df <- df %>% 
    group_by(Tissue, value) %>% 
    mutate(jitter = ifelse(n()>1, value+runif(1, min=-0.15, max=0.15), value)) 

輸出:

Source: local data frame [9 x 3] 
Groups: Tissue, value [4] 

     value Tissue  jitter 
     (dbl) (fctr)  (dbl) 
1 1.051552 Vis 1.1793382 
2 1.051552 Vis 1.1793382 
3 1.051552 Vis 1.1793382 
4 11.976925 Testes 11.9769250 
5 1.051552 Vis 1.1793382 
6 1.051552 Spleen 1.0515524 
7 1.051552 Vis 1.1793382 
8 1.051552 Brain 0.9284923 
9 1.051552 Brain 0.9284923 

第4,6行是正確unjittered。但行[1-3,5,7]我想有獨特的抖動。來自dplyr更好的人的任何想法? :(

+1

而不是'runif(1,...)'add'runif(n(),...)'。 – Gregor

+3

@Gregor仍然不能工作,因爲他們由於某種原因而被「Tissue」和「value」分組。雖然僅由'Tissue'進行分組時,它將不起作用,因爲條件長度爲1,因此'ifelse'將總是返回長度爲1的結果。'ifelse'通常很糟糕的原因之一。 –

+0

我會保留最後一句:) –

回答

3

正如在評論中指出,ifelse()在這種情況下,問題的,因爲什麼它返回必須相同測試的時間長度。因爲你的測試是一個長度爲1的長度,ifelse不會返回隨機數。的

長度n()我們可以通過邏輯與否n() > 1的抖動值乘以解決這個問題如果是假,它會被乘以0;如果爲真,由1

df %>% 
    group_by(Tissue, value) %>% 
    mutate(
     jitter = value + runif(n(), min = -0.15, max = 0.15) * (n() > 1) 
    ) 
#  value Tissue  jitter 
#  (dbl) (fctr)  (dbl) 
# 1 1.051552 Vis 1.1020925 
# 2 1.051552 Vis 1.1398244 
# 3 1.051552 Vis 0.9339355 
# 4 11.976925 Testes 11.9769250 
# 5 1.051552 Vis 1.1186657 
# 6 1.051552 Spleen 1.0515524 
# 7 1.051552 Vis 1.0249348 
# 8 1.051552 Brain 1.0814222 
# 9 1.051552 Brain 1.0496148 

隨着一個單一的條件,你實際上可以使用plain的if(){} else ,這也可以在mutate內工作:

jitter = value + if(n() > 1) {runif(n(), -.15, .15)} else 0 

你更喜歡哪一個取決於你。

+0

我應該注意到我是一個白癡,並要求抖動錯誤的列。我實際上是在尋找'jitter = as.numeric(Tissue)+ runif(n(),min = -0.15,max = 0.15)*(n()> 1)'。 – fanli

+1

你可以用'jitter(0 * value,amount = 0.15)'替換'runif(n(),min = -0.15,max = 0.15)'(但是很難理解發生了什麼) – jaimedash