#r #pivot #tidyverse
#r #сводная #tidyverse
Вопрос:
Я пытаюсь отфильтровать все записи, содержащие систематический NA, по подмножеству числовых столбцов.
Вот игрушечный пример.
library(tidyverse)
df <- tibble(
year = c(2001, 2002, 2003, 2001, 2002, 2003, 2001),
rank = c(12, 25, 65, NA, NA, NA, NA),
category = c("a", "a", "b", "c", "c", "c", NA),
other = c("x", "y", "x", "y", "x", "y", "x")
)
df %>%
pivot_wider(names_from = year, values_from = rank) %>%
filter(.cols = c(2001:2003),
.fns = ~ !is.na(.x))
Этот код не работает, он не может распознать столбцы 2001:2003
— Каков правильный способ удаления третьей записи путем фильтрации всех NA для столбцов 2001, 2002, 2003.
Диапазон столбцов должен быть указан как диапазон аналогично тому, как я делаю 2001: 2003.
Запись «c» должна быть отфильтрована, но не запись, в которой все столбцы являются NA (последний в примере с игрушкой)
Это ошибка, которую я получаю :
Ошибка: проблема с
filter()
вводом..1
. Ввод x..1
именован. ℹ Обычно это означает, что вы использовали=
вместо==
. ℹ Вы имели в виду.cols == c(2001:2003)
?
Комментарии:
1. Вы хотите удалить категорию c, поскольку все с 2001 по 2003 год являются NAs?
2. Все записи, содержащие NA для столбцов 2011: 2003, выглядят как запись
c
, но она может быть любой другой3. Почему не просто
df %>% drop_na() %>% pivot_wider(...)
?4. поскольку drop_na удалит все NA для всех столбцов, а не для 2001: 2003 — я уточню пример
5. Данные, с которыми я имею дело, представлены в широком формате, и именно так я должен их хранить —
df
это помощник.
Ответ №1:
Вы можете фильтровать по столбцам. Использовать across
df %>%
pivot_wider(names_from = year, values_from = rank) %>%
filter(rowSums(!across(`2001`:`2003`, is.na)) > 0L)
Вывод
# A tibble: 3 x 5
category other `2001` `2002` `2003`
<chr> <chr> <dbl> <dbl> <dbl>
1 a x 12 NA NA
2 a y NA 25 NA
3 b x NA NA 65
Ответ №2:
Насколько мне известно, вы не можете фильтровать по столбцам. Вы можете выбирать только по столбцам. Вот что я бы сделал.
df %>%
pivot_wider(names_from = year, values_from = rank) %>%
pivot_longer(2:4) %>%
group_by(name) %>%
filter(!any(is.na(value)))
Ответ №3:
Возможно, было бы лучше filter
перед выполнением pivot_wider
library(dplyr)
library(tidyr)
df %>%
group_by(category, other) %>%
filter(any(!is.na(rank))) %>%
ungroup %>%
pivot_wider(names_from = year, values_from = rank)
-вывод
# A tibble: 3 x 5
# category other `2001` `2002` `2003`
# <chr> <chr> <dbl> <dbl> <dbl>
#1 a x 12 NA NA
#2 a y NA 25 NA
#3 b x NA NA 65
Комментарии:
1. Действительно, но данные, с которыми я работаю, поступают в широкоформатном формате — я использовал игрушечный пример, чтобы перейти к формату моих данных, чтобы объяснить проблему.