计算 data.table 中某行的一部分中的 NA
Counting the NA's in a part of a row in data.table
我有一个数据集 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
我们可以使用 apply
计算非 NA
(对于列 questionA
、questionB
和 questionC
,即列号 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
使用 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")]))
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])]
我有一个数据集 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
我们可以使用 apply
计算非 NA
(对于列 questionA
、questionB
和 questionC
,即列号 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
使用 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")]))
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])]