Я хотел бы свернуть несколько условий строки, используя tidyverse, и вот мой пример

df <- data.frame(value = c(2,2,2,2,1,1,1,1,1,1),
                 name1 = c("a", "a", "b", "b", 'c', "d", "e", NA, NA, NA),
                 name2 = c("x", "x", "x", "x", "x", "x", "y", NA, NA, NA))

Я хотел бы свернуть строки, сказав, что name1 то же самое, что и name2 то же самое, тогда эти строки будут свернуты в одну строку. Есть предложения для меня?

Мой желаемый результат вроде

value name1 name2
1      2     a     x
2      2     b     x
3      1     c     x
4      1     d     x
5      1     e     y
6      1  <NA>  <NA>
7      1  <NA>  <NA>
8     1  <NA>  <NA>
2
Anh 11 Окт 2021 в 21:22

3 ответа

Лучший ответ

Может быть это поможет

library(dplyr)
df %>% 
    filter(!duplicated(across(everything()))|if_any(everything(), is.na))

-вывод

 value name1 name2
1     2     a     x
2     2     b     x
3     1     c     x
4     1     d     x
5     1     e     y
6     1  <NA>  <NA>
7     1  <NA>  <NA>
8     1  <NA>  <NA>

Если он основан на выбранном количестве столбцов

df %>%
    filter(!duplicated(across(c(name1, name2)))|if_any(c(name1, name2), is.na))

Или в base R

 df[!duplicated(df)|rowSums(is.na(df)) > 0,]
   value name1 name2
1      2     a     x
3      2     b     x
5      1     c     x
6      1     d     x
7      1     e     y
8      1  <NA>  <NA>
9      1  <NA>  <NA>
10     1  <NA>  <NA>
2
akrun 11 Окт 2021 в 18:37

Другой вариант тидиверса может выглядеть следующим образом.

library(dplyr)

df %>%
  filter(if_any(name1:name2, ~ !is.na(.))) %>%
  distinct() %>%
  bind_rows(filter(df, if_any(name1:name2, is.na)))

#   value name1 name2
# 1     2     a     x
# 2     2     b     x
# 3     1     c     x
# 4     1     d     x
# 5     1     e     y
# 6     1  <NA>  <NA>
# 7     1  <NA>  <NA>
# 8     1  <NA>  <NA>
1
rjen 11 Окт 2021 в 19:00

Вот альтернатива dplyr, использующая столбец helper для подготовки к применению distinct()

library(dplyr)
df %>% 
  mutate(helper = paste0(name1, name2),
         helper = ifelse(is.na(name1) | is.na(name2), 
                         paste0(helper, row_number()), helper)
         ) %>% 
  distinct(helper, .keep_all = TRUE) %>% 
  select(-helper)

Итог:

  value name1 name2
1     2     a     x
2     2     b     x
3     1     c     x
4     1     d     x
5     1     e     y
6     1  <NA>  <NA>
7     1  <NA>  <NA>
8     1  <NA>  <NA>
1
TarJae 11 Окт 2021 в 19:02