聚合/计算非NA值的数量

时间:2018-03-07 14:19:25

标签: r dataframe dplyr

我正在尝试计算列中非NA值的数量,然后将该数字与相邻的日期时间列进行汇总。例如,获取此数据集(让我们称之为df):

##    DateTime    V1      V2      V3
01   02-10-2018   fire    1       NA
02   02-10-2018   water   4       NA
03   02-10-2018   fire    2       NA
04   02-10-2018   fire    2       NA
05   02-10-2018   water   8       NA
06   02-11-2018   water   NA      NA
07   02-11-2018   fire    4       NA
08   02-12-2018   earth   4       NA
09   02-13-2018   fire    NA      NA
10   02-13-2018   fire    NA      NA
11   02-13-2018   fire    4       NA

我想以这种格式出示一张桌子:

##    DateTime      V1      V2      V3
01    02-10-2018    5        5       0
02    02-11-2018    2        1       0
03    02-12-2018    1        1       0
04    02-13-2018    3        1       0

我已经尝试了几种解决方案,但是让我失望的是我有一行充满NA的值会抛出一个空的数据集并且不断弄乱代码。

尝试的解决方案:

data.frame( table (df$DateTime, df$V1))

df%>%
select(df$DateTime,df$V1)%>%
filter(!is.na(df$V1))%>%
group_by(df$DateTime)%>%
mutate(V1.count = n())%>%
slice(1)

3 个答案:

答案 0 :(得分:3)

您可以使用summarise_at中的dplyr

library(dplyr)   

count_nas <- function(x) sum(!is.na(x))

my_df %>% 
  group_by(V2) %>% 
  summarise_at(vars(V3:V5), count_nas)
# # A tibble: 4 x 4
#   V2            V3    V4    V5
#   <chr>      <int> <int> <int>
# 1 02-10-2018     5     5     0
# 2 02-11-2018     2     1     0
# 3 02-12-2018     1     1     0
# 4 02-13-2018     3     1     0

更简洁的版本是简单地创建内联函数:

my_df %>% 
  group_by(V2) %>% 
  summarise_at(vars(V3:V5), funs(sum(!is.na(.))))

答案 1 :(得分:2)

aggregate(df1[-1], df1[1], function(x) sum(!is.na(x)))
#OR
aggregate(df1[!names(df1) %in% "DateTime"], df1["DateTime"], function(x) sum(!is.na(x)))
#    DateTime V1 V2 V3
#1 02-10-2018  5  5  0
#2 02-11-2018  2  1  0
#3 02-12-2018  1  1  0
#4 02-13-2018  3  1  0

数据

df1 = structure(list(DateTime = c("02-10-2018", "02-10-2018", "02-10-2018", 
"02-10-2018", "02-10-2018", "02-11-2018", "02-11-2018", "02-12-2018", 
"02-13-2018", "02-13-2018", "02-13-2018"), V1 = c("fire", "water", 
"fire", "fire", "water", "water", "fire", "earth", "fire", "fire", 
"fire"), V2 = c(1L, 4L, 2L, 2L, 8L, NA, 4L, 4L, NA, NA, 4L), 
    V3 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), .Names = c("DateTime", 
"V1", "V2", "V3"), class = "data.frame", row.names = c("01", 
"02", "03", "04", "05", "06", "07", "08", "09", "10", "11"))

答案 2 :(得分:0)

这是一个解决方案:

df %>% 
group_by(DateTime) %>% 
summarise(V1 = sum(!is.na(V1)),
          V2 = sum(!is.na(V2)),
          V3 = sum(!is.na(V3)))