删除具有特定NA编号的组

人气:524 发布:2022-10-16 标签: r grouping filter na

问题描述

很抱歉打扰您回答一个相对简单的问题。 我有这种类型的数据帧:

"姓名"列c(a,b,c,d,e...)中的一长串姓名,"姓氏"列c(A,B)中的两个可能的类别,以及包含值的第三列。 我希望删除至少在一个姓氏类的值列中有超过2个"NA"的所有姓名。 我想发布一个示例数据集,但我正在努力将其正确格式化

我正在尝试使用

  df <- df %>% 
  group_by(NAME) %>% 
  group_by(SURNAME) %>% 
  filter(!is.na(VALUE)) %>% 
  filter(length(VALUE)>=3)

它不会引发错误,但我感觉有些地方不对劲。有什么建议吗?非常感谢

推荐答案

让我们创建一个要使用的数据集:

set.seed(1234)
df <- data.frame(
    name     = sample(x=letters,       size=1e3, replace=TRUE),
    surname  = sample(x=c("A", "B"),   size=1e3, replace=TRUE),
    value    = sample(x=c(1:10*10,NA), size=1e3, replace=TRUE),
    stringsAsFactors = FALSE
)

下面介绍如何使用Base R:

# count NAs by name-surname combos (na.action arg is important!)
agg <- aggregate(value ~ name + surname, data=df, FUN=function(x) sum(is.na(x)), na.action=NULL)

# rename is count of NAs column
names(agg)[3] <- "number_of_na"

#add count of NAs back to original data
df <- merge(df, agg, by=c("name", "surname"))

# subset the original data
result <- df[df$number_of_na < 3, ]

以下是如何处理数据。表:

library(data.table)
dt <- as.data.table(df)

dt[ , number_of_na := sum(is.na(value)), by=.(name, surname)]
result <- dt[number_of_na < 3]

以下是如何使用dplr/tidyverse:

library(dplyr) # or library(tidyverse)
result <- df %>% 
    group_by(name, surname) %>% 
    summarize(number_of_na = sum(is.na(value))) %>% 
    right_join(df, by=c("name", "surname")) %>% 
    filter(number_of_na < 3)

124