R двухрядный фильтр по строке - PullRequest
0 голосов
/ 03 октября 2018

Я очищаю набор данных, у которого еще нет имен столбцов (поэтому я работаю с индексами), и я пытаюсь отфильтровать два столбца df, передав результаты первого фильтра во второй ине понимаю, почему ниже не работает:

stripcols <- c("","Total+")

df <- df %>% 
  filter(!df[,1] %in% stripcols) %>% 
  filter(!df[,2] %in% stripcols)

Запуск это приводит к:

Error in filter_impl(.data, quo) : Result must have length 46, not 58

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

Мне также любопытно, есть ли способ сделать это с помощью одной команды фильтра, которая применяется к обоим столбцам, а не к двум.

1 Ответ

0 голосов
/ 03 октября 2018

Источником ошибки является то, что вы всегда сравниваете строки nrow(df) независимо от того, сколько строк попало во вторую filter.Например:

dat <- data.frame(a=1:10)
dat %>% filter(a > 5)
#    a
# 1  6
# 2  7
# 3  8
# 4  9
# 5 10

То, как вы пишете, вы делаете

dat %>% filter(dat[,1] > 5)
#    a
# 1  6
# 2  7
# 3  8
# 4  9
# 5 10

Для этого первого вызова, количество строк, которые идут в filter равно 10, а число сравниваемых строк внутри filter также равно 10. Однако, если вы должны были сделать:

dat %>% filter(dat[,1] > 5) %>% filter(dat[,1] > 7)
# Error in filter_impl(.data, quo) : Result must have length 5, not 10

, это не удастся, так как числоколичество строк, входящих во вторую filter, составляет всего 5, а не 10, хотя мы даем * 10 9 * команду 10 сравнений, используя dat[,1].

(NB: многие комментарии об именах совершенно уместны, нодавайте продолжим тему использования индексов столбцов.)

Первый трюк состоит в том, чтобы дать каждому filter только столько сравнений, сколько поступают данные. Другой способ сказать, что это сравнение состоянийданные на тот момент времени.magrittr (и, следовательно, dplyr) сделать это с помощью заполнителя ..Точка всегда может быть выведена (по умолчанию первый аргумент функции RHS, функция после %>%), но некоторые считают, что явное выражение лучше.Например, это допустимо:

mtcars %>%
  group_by(cyl) %>%
  tally()
# # A tibble: 3 x 2
#     cyl     n
#   <dbl> <int>
# 1     4    11
# 2     6     7
# 3     8    14

, но явно эквивалентный канал такой:

mtcars %>%
  group_by(., cyl) %>%
  tally(.)

Если первым аргументом функции является не сам фрейм, то %>% Вывод пути не удастся:

mtcars %>%
  xtabs(~ cyl + vs)
# Error in as.data.frame.default(data, optional = TRUE) : 
#   cannot coerce class '"formula"' to a data.frame

(Поскольку он фактически вызывает xtabs(., ~cyl + vs) и без именованных аргументов, тогда xtabs предполагал, что первый аргумент будет formula.)

поэтому мы должны быть явными в следующих ситуациях:

mtcars %>%
  xtabs(~ cyl + vs, data = .)
#    vs
# cyl  0  1
#   4  1 10
#   6  3  4
#   8 14  0

(надуманный пример, предоставлен).Можно было бы также сделать mtcars %>% xtabs(formula=~cyl+vs), но мои очки стоят.

Так что, чтобы адаптировать ваш код, я ожидал бы, что это сработает:

df %>% 
  filter(!.[,1] %in% stripcols) %>% 
  filter(!.[,2] %in% stripcols)

Я думаю, что предпочел бы [[ подход (частично потому, что я знаю, что tbl_df и data.frame имеют дело с [,1] немного по-другому ... и хотя он работает с ним, я все же предпочитаю явность [[):

df %>% 
  filter(!.[[1]] %in% stripcols) %>% 
  filter(!.[[2]] %in% stripcols)

который должен работать.Конечно, комбинирование тоже работает отлично:

df %>% 
  filter(!.[[1]] %in% stripcols, !.[[2]] %in% stripcols)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...