【问题标题】:Counting the NA's in a part of a row in data.table在 data.table 的一行中计算 NA
【发布时间】:2019-03-01 23:48:24
【问题描述】:

我有一个数据集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

【问题讨论】:

标签: r sum data.table na


【解决方案1】:

我们可以使用apply 计算非NA(对于列questionAquestionBquestionC 即列号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

【讨论】:

  • 可以缩短为:apply(df[,3:5], 1, function(x) sum(!is.na(x)))
  • @snoram:感谢您的建议。我也采纳了你的建议:)
  • @snoram 或:rowSums(!is.na(df[,3:5]))
【解决方案2】:

使用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")]))

【讨论】:

  • 非常感谢!我选择简单、接近我自己的方法并提供基本解决方案。
【解决方案3】:

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])]

【讨论】:

  • 你可以去掉 as.matrix()
猜你喜欢
  • 2018-08-28
  • 1970-01-01
  • 2013-01-19
  • 1970-01-01
  • 1970-01-01
  • 2014-08-06
  • 1970-01-01
  • 2023-03-17
相关资源
最近更新 更多