Фильтровать NA, только если группа имеет более 1 наблюдения в dplyr

Я хотел бы иметь возможность сохранять NA только для групп, которые имеют более двух записей, и просто хочу оставить в покое любые группы, у которых есть 1 запись (независимо от того, есть у них NA или нет). То есть, если в группе два элемента, оставьте только NA. Если он есть, просто возьмите то, что есть. Вот репрекс типа данных, которые у меня есть:

library(dplyr)

data <- data.frame(
  x = c(1, NA_real_, 3, NA_real_),
  y = c("grp1", "grp2", "grp2", "grp3")
)
data
#>    x    y
#> 1  1 grp1
#> 2 NA grp2
#> 3  3 grp2
#> 4 NA grp3

Тогда вот довольно уродливый способ, которым я добился того, что хочу:

raw <- data %>%
  group_by(y) %>%
  mutate(n = n())

results <- bind_rows(
  raw %>%
    filter(n == 2) %>%
    filter(is.na(x)),
  raw %>%
    filter(n == 1)
) %>%
  ungroup() %>%
  select(-n)

results
#> # A tibble: 3 × 2
#>       x y    
#>   <dbl> <chr>
#> 1    NA grp2 
#> 2     1 grp1 
#> 3    NA grp3

Не могли бы вы поделиться ожидаемым результатом? В соответствии с вашей проблемой должно быть одно наблюдение для группы 2, имеющее значение 3.

Neeraj 18.11.2022 20:18
Шаблоны Angular PrimeNg
Шаблоны Angular PrimeNg
Как привнести проверку типов в наши шаблоны Angular, использующие компоненты библиотеки PrimeNg, и настроить их отображение с помощью встроенной...
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Начала с розового дизайна
Начала с розового дизайна
Pink Design - это система дизайна Appwrite с открытым исходным кодом для создания последовательных и многократно используемых пользовательских...
Шлюз в PHP
Шлюз в PHP
API-шлюз (AG) - это сервер, который действует как единая точка входа для набора микросервисов.
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
4
1
61
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Обновление после уточнения: нам нужно только добавить ! и заменить == на >:

library(dplyr)
data %>% 
  group_by(y) %>% 
  filter(!(!is.na(x) & n() > 1))

      x y    
  <dbl> <chr>
1     1 grp1 
2    NA grp2 
3    NA grp3 

Мы могли бы определить filter с помощью max(row_number(): обновление: вместо max(row_number() мы могли бы использовать n() (большое спасибо @Juan C)

library(dplyr)
data %>% 
  group_by(y) %>% 
   filter(!(is.na(x) & n() == 1))
 # filter(!(is.na(x) & max(row_number()) == 1))
     x y    
  <dbl> <chr>
1     1 grp1 
2    NA grp2 
3     3 grp2 

Вы могли бы упростить max(row_number()) == 1) с помощью n() == 1, верно?

Juan C 18.11.2022 20:19

:-) Большое спасибо, я всегда забываю об этом n().

TarJae 18.11.2022 20:20

Разве вывод здесь не отличается от ожидаемого в Q? result из ОП сохранил x = NA для grp3?

Josh White 18.11.2022 20:23

Я смущен. Но я понял, что «сохранять NA только для групп, которые имеют более двух записей» звучит так, как будто ОП хотел удалить только NA, где в группе находится только одна запись ?! ОП должен уточнить. В любом случае ответ отличается от одного !

TarJae 18.11.2022 20:28

Я попытался уточнить вопрос. Но, как указывает @JoshWhite, это ответ, отличный от ожидаемого.

boshek 19.11.2022 00:16
Ответ принят как подходящий

Вот еще один подход, который работает

data %>% 
  group_by(y) %>%  
  filter(!(!is.na(x) & n() > 1))
# A tibble: 3 × 2
# Groups:   y [3]
      x y    
  <dbl> <chr>
1     1 grp1 
2    NA grp2 
3    NA grp3

Я думаю, что это не очень большая проблема. Мы можем поменять местами `filter(!(!is.na(x) & n() > 1))` на `filter(!( is.na(x) & n() > 1))`, чтобы получить оба решения. Это все о !.

TarJae 18.11.2022 20:39

Правда, я просто следовал ожидаемому результату ОП, а не его словам. К счастью, они получают ответ на оба вопроса!

Josh White 18.11.2022 20:41

Вы специально просили сделать это с помощью dplyr, однако вы можете сделать это с помощью data.table. Более интуитивно понятно:

library(data.table)
setDT(data)
data <- data[, N := .N, by = y][N <= 1 | !is.na(x)][, N := NULL]
data

Вывод:

   x    y
1:  1 grp1
2:  3 grp2
3: NA grp3

Если цель состоит в том, чтобы сохранить случаи NA, если группа имеет более одного наблюдения, выполните следующие действия:

data <- data[, N := .N, by = y][N <= 1 | is.na(x)][, N := NULL]
data

Вывод:

    x    y
1:  1 grp1
2: NA grp2
3: NA grp3

То же самое здесь. Разве вывод здесь не отличается от ожидаемого в Q? result из ОП сохранил x = NA для grp3?

Josh White 18.11.2022 20:28

Он читал, фильтровать NA, если группа имеет более одного наблюдения. Я подумал, что это означает удаление случая NA, если группа имеет более одного NA.

Neeraj 18.11.2022 20:30

"держать NA". Извините за путаницу

boshek 19.11.2022 00:16

Другие вопросы по теме