2015-10-18 45 views
1

第1部分我有以下數據表。我想創建一個新的列,其中包含每個id出現的數字,其中有任何樣式值,但NA除外。主要問題是我不知道如何處理NA。目前,當NA存在我得到的1將一列中的NAs作爲零頻率的兩列頻率

id style 
1  A  
1  A  
2  A  
2  B  
3  NA  
4  A  
4  C 
5  NA 

我使用下面的嘗試頻率,但它仍然被NA

dt[, allele_count := .N, by = list(pat_id, style)] 

所需的數據表將如下所示:

id style count 
1  A  2 
1  A  2 
2  A  2 
2  B  2 
3  NA  0 
4  A  4 
4  B  4 
4  B  4 
4  C  4 
5  NA  0 

第2部分我還希望能夠添加另一列,其數目爲每個id具有一定的樣式值。

id style count2 
1  A  2 
1  A  2 
2  A  1 
2  B  1 
3  NA  0 
4  A  1 
4  B  2 
4  B  2 
4  C  1 
5  NA  0 

獎金問題:而不是看多少次id發生與給定style值作爲第2部分,你怎麼能計算不同style值數爲每個id,如如下。

id style count3 
1  A  1 
1  A  1 
2  A  2 
2  B  2 
3  NA  0 
4  A  3 
4  B  3 
4  B  3 
4  C  3 
5  NA  0 
+0

不確定第一個計數...例如,如果另一個id = 3的樣式爲B,您可以在此示例中添加預期結果嗎? (也檢查你的初始data.table,因爲它沒有四個id = 4 ...) – digEmAll

+0

期望的輸出與給定的輸入不匹配。 –

回答

3

這裏有一個可能性。基本上我們使用一個行子集來分配新列,然後在所有三個新列中將NA值替換爲最後的零。

nna <- !is.na(dt$style) ## so we don't have to call it four times 
dt[nna, count := .N, by = id][nna, count2 := .N, by = .(id, style)][ 
    nna, count3 := uniqueN(style), by = id][!nna, names(dt)[3:5] := 0L] 

導致

id style count count2 count3 
1: 1  A  2  2  1 
2: 1  A  2  2  1 
3: 2  A  2  1  2 
4: 2  B  2  1  2 
5: 3 NA  0  0  0 
6: 4  A  2  1  2 
7: 4  C  2  1  2 
8: 5 NA  0  0  0 

或者你也可以簡化這個下到下面,然後在必要時重新排序的列。

dt[nna, c("count", "count3") := .(.N, uniqueN(style)), by = id][ 
    nna, count2 := .N, by = .(id, style)][!nna, names(dt)[3:5] := 0L] 

請注意,此方法與其他發佈的答案非常相似。我不確定哪兩個是首選方法,行子集或if()聲明。

+0

那也好!謝謝! – ejg

2

這是一個可能的解決方案:

library(data.table) 

dt <- data.table(id=c(1,1,2,2,3,4,4,5), 
       style=c('A','A','A','B',NA,'A','C',NA)) 

# count = number of ids having ALL styles defined 
dt[, count := if(any(is.na(style))) 0L else .N, by = id] 
# count2 = number of id-style occurrences (0 if style = NA) 
dt[, count2 := if(is.na(style)) 0L else .N, by = .(id, style)] 


> dt 
    id style count count2 
1: 1  A  2  2 
2: 1  A  2  2 
3: 2  A  2  1 
4: 2  B  2  1 
5: 3 NA  0  0 
6: 4  A  2  1 
7: 4  C  2  1 
8: 5 NA  0  0 

獎金:

dt[, count3 := uniqueN(na.omit(style)), by = id] 

> dt 
    id style count count2 count3 
1: 1  A  2  2  1 
2: 1  A  2  2  1 
3: 2  A  2  1  2 
4: 2  B  2  1  2 
5: 3 NA  0  0  0 
6: 4  A  2  1  2 
7: 4  C  2  1  2 
8: 5 NA  0  0  0 
+1

對於條件向量> 1的情況,應該保存'ifelse'。'any(..)'將總是產生長度爲1的邏輯。在這種情況下,if(any(is.na(style)))0L else .N'最有可能是更好的控制流。但是,如果兩者都發生了工作,就像這個案例一樣,可能會有爭議。 –

+0

在這種情況下,結果完全相同(我故意使用ifelse函數,因爲我不喜歡單行if語句)。你認爲ifelse效率較低? – digEmAll

+1

我認爲這更「正確」。但是我總是打破規範的規則。這兩種表述的行爲有所不同,因爲許多新用戶可能會認爲它們是可以互換的。 –