R分组,计算非NA值

Mis*_*mer 5 r

我有一个散布 NA 的数据框

toy_df
# Y  X1 X2 Label
# 5  3  3  A
# 3  NA 2  B
# 3  NA NA C
# 2  NA 6  B
Run Code Online (Sandbox Code Playgroud)

我想按标签字段对其进行分组,并计算每个标签的每个变量中有多少非 NA 值。

desired output:
# Label Y  X1 X2
# A     1  1  1
# B     2  0  2
# C     1  0  0
Run Code Online (Sandbox Code Playgroud)

目前我已经使用循环完成了这项工作,但它又慢又不整洁,我相信有更好的方法。

聚合似乎达到了一半,但它包括 NA 的计数。

aggregate(toy_df, list(toy_df$label), FUN=length)
Run Code Online (Sandbox Code Playgroud)

任何想法表示赞赏...

akr*_*run 8

我们可以使用data.table. 将'data.frame' 转换为'data.table' ( setDT(toy_df)),按'Label' 分组,循环遍历Data.table ( .SD)的子集并获取sum非NA 值( !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
Run Code Online (Sandbox Code Playgroud)

或者dplyr使用相同的方法

library(dplyr)
toy_df %>% 
      group_by(Label) %>%
      summarise_each(funs(sum(!is.na(.))))
Run Code Online (Sandbox Code Playgroud)

base R与选择by,并colSums通过对逻辑矩阵第4列编组(!is.na(toy_df[-4])

by(!is.na(toy_df[-4]), toy_df[4], FUN = colSums)
Run Code Online (Sandbox Code Playgroud)

或者使用rowsum与 in 类似的方法,by除了使用该rowsum函数。

rowsum(+(!is.na(toy_df[-4])), group=toy_df[,4])
#  Y X1 X2
#A 1  1  1
#B 2  0  2
#C 1  0  0
Run Code Online (Sandbox Code Playgroud)