我有一个散布了NA的数据框
toy_df
# Y X1 X2 Label
# 5 3 3 A
# 3 NA 2 B
# 3 NA NA C
# 2 NA 6 B
我想通过标签字段对此进行分组,并计算每个标签的每个变量中有多少非NA值。
desired output:
# Label Y X1 X2
# A 1 1 1
# B 2 0 2
# C 1 0 0
我现在已经使用循环完成了这项工作,但它很慢而且不整洁,我确信有更好的方法。
聚合似乎在那里得到了一半,但它包括计数中的NA。
aggregate(toy_df, list(toy_df$label), FUN=length)
任何想法都赞赏......
答案 0 :(得分:4)
我们可以使用data.table
。转换' data.frame'到' data.table' (setDT(toy_df)
)按标签'分组,循环显示Data.table(.SD
)的子集,并获取{NA}值的sum
({{ 1}})
!is.na(x)
或library(data.table)
setDT(toy_df)[, lapply(.SD, function(x) sum(!is.na(x))), by = Label]
# Label Y X1 X2
#1: A 1 1 1
#2: B 2 0 2
#3: C 1 0 0
使用相同的方法
dplyr
或library(dplyr)
toy_df %>%
group_by(Label) %>%
summarise_each(funs(sum(!is.na(.))))
选项base R
和by
按逻辑矩阵(colSums
)的第4列分组
!is.na(toy_df[-4])
或by(!is.na(toy_df[-4]), toy_df[4], FUN = colSums)
采用与rowsum
类似的方法,但使用by
函数除外。
rowsum
答案 1 :(得分:2)
或在基地R
aggregate(toy_df[,1:3], by=list(toy_df$Label), FUN=function(x) { sum(!is.na(x))})
答案 2 :(得分:1)
aggregate(cbind(toy_df$Y, toy_df$X1, toy_df$X2), list(toy_df$label),
FUN = function (x) sum(!is.na(x)))