2017-01-04 9 views
3

私はすでにコメントに本当に良い答えがあると思いますが、私は将来の参考になるように質問を言い換えるつもりです。合計NA以外の要素だけを集計しますが、すべてのNAがNAを返す場合

私はdata.tableを使用してグループ別に集計しようとしています。問題は、いくつかのグループだけがNAを持っているということです。これらのグループについては、合計がNAを返すようにしたいと思います。しかし、NAとは異なる1つの値を持つ1つのグループがある場合は、非NA値の合計を取得したいと考えています。

A <- data.table(col1= c('A','A','B','B','C','C'), 
       col2= c(NA,NA,2,3,NA,4)) 

この引数na.rm = Tを添加せずに、グループCは、それがNAを返すべきときにグループAにna.rm = T戻り0を付加すること、ただし前記

A[, sum(col2), by = .(col1)] 
    col1 V1 
1: A NA 
2: B 5 
3: C NA 

を返すべきときにNAを返します。 、

ifelse(all(is.na(col2)), NA, sum(col2, na.rm = T) 

私はそれを回避するための関数を作成しました:私が一番好きな

A[, sum(col2, na.rm = T), by = .(col1)] 
    col1 V1 
1: A 0 
2: B 5 
3: C 4 

アプローチは、私が書いた以下の機能に似ているコメントで提案sandipan 1であり、私はこれを回避するために、すでに組み込みの方法があるかどうかを確認していない:

sum.na <- function(df){ 

    if (all(is.na(df))){ 

    suma <- NA 
    } 
    else {  
    suma <- sum(df, na.rm = T) 
    } 

    return(suma) 
} 
+1

data.tableを含む例を表示できますか?一般的に... 'DT [!is(na)、sumx:= sum(x)、by = id]'は動作するはずです。 – Frank

+0

'x'がベクトルであれば、これはうまくいくはずです:' ifelse(all(is.na(x))、NA、sum(x、na.rm = TRUE)) ' –

+0

@sandipan Fyi、' anyNA '' any(is.na(x)) 'と等価です。' .. hm、ちょうどここで助けにならないでしょう。 – Frank

答えて

2

他のユーザーからの提案に続いて、私は私の質問への答えを投稿します。質問で述べたように、あなたは、NASが含まれている1列の値を合計する必要がある場合は、2つの良いアプローチがあり、

:溶液は上記のコメントに@sandipanによって提供された

1)ifelse使用@Frankが指摘したように、私はエラーを取得して保持するので、私はNA_integer_を追加

suma = function(x) if (all(is.na(x))) x[NA_integer_] else sum(x, na.rm = TRUE) 

A[, suma(col2), by = .(col1)] 

注:@Frankにより示唆されるように

A[, (ifelse(all(is.na(col2)), col2[NA_integer_], sum(col2, na.rm = T))), 
    by = .(col1)] 

2)は、関数を定義しますタイプについて。

関連する問題