计算data.table中一行的一部分中的NA

时间:2018-09-26 08:51:57

标签: r sum data.table na

我有一个数据集df,其结构类似于下面的示例:

nr countrycode questionA questionB questionC WeightquestionA WeightquestionB WeightquestionC
1  NLD               2         1         4         0.6             0.2             0.2
2  NLD               NA        4         NA        0.4             0.4             0.2
3  NLD               4         4         1         0.2             0.2             0.6
4  BLG               1         NA        1         0.1             0.5             0.4
5  BLG               5         3         5         0.2             0.2             0.6

问题A,B和C与相似的主题相关,因此,我想考虑所有问题(WeightquestionA WeightquestionB WeightquestionC的重要性,为所有问题创建一个平均分。

目前,我已经手动计算了平均分数。

(questionA*WeightquestionA) + (questionB*WeightquestionB) + (questionC*WeightquestionC)

如果不是NA的问题,这将不是一个无法解决的问题(对于这些问题:不能将它们删除)。因此,我想使该过程自动化。

我目前正在考虑使用sum(!is.na())对每一行(1到5)的每个问题(A,B,C)中的非NA进行计数,并将该值放入新列中。

但是,使用data.table我总是很难正确地使用语法。我相信应该是这样的:

df[, NonNA:=sum(!is.na(questionA + questionB + questionC))]

但是,这将对列中的所有NA求和,而不是针对每一行。我应该如何编写每行计算的语法?

我想按名称分别引用各列,因为它们在实际df中并不相邻。

所需的输出:

nr countrycode qA qB qC WeightquestionA WeightquestionB WeightquestionC NonNA
1  NLD         2  1  4         0.6             0.2             0.2      3
2  NLD         NA 4  NA        0.4             0.4             0.2      1
3  NLD         4  4  1         0.2             0.2             0.6      3
4  BLG         1  NA 1         0.1             0.5             0.4      2
5  BLG         5  3  5         0.2             0.2             0.6      3

3 个答案:

答案 0 :(得分:1)

我们可以使用NA来计算非questionA(对于questionBquestionCapply,即第3至5列): >

df$nonNA=apply(df[,3:5], 1, function(x) length(which(!is.na(x))))

或(来自snoarm的建议)

df$nonNA=apply(df[,3:5], 1, function(x) sum(!is.na(x)))

示例输出:

   questionA questionB questionC nonNA
1         2         1         4     3
2        NA         4        NA     1
3         4         4         1     3
4         1        NA         1     2
5         5         3         5     3

答案 1 :(得分:1)

使用data.table,您可以这样做:

df[, NonNA := sum(!is.na(questionA), !is.na(questionB), !is.na(questionC)), by = .(nr)]

基本解决方案:

df$nonNA <- rowSums(!is.na(df[,c("questionA", "questionB", "questionC")]))

答案 2 :(得分:1)

snoram推荐的另一种选择:

df[, NonNA := rowSums(!is.na(.SD)), 
    .SDcols=paste0("question", LETTERS[1:3])]

还有:

df[, NonNA := Reduce(function(x, y) x + !is.na(y), .SD, init=rep(0L, .N)), 
    .SDcols=paste0("question", LETTERS[1:3])]