Почему медиана и объединение не работают с неравным числом строк? - PullRequest
3 голосов
/ 06 марта 2020

В недавнем вопросе я пытался дать ответ, используя dplyr::coalesce, чтобы заменить NA сгруппированным медианой. Но я получил ошибку

Error: Argument 2 must be an integer vector, not a double vector

. Пытаясь выяснить, что послужило причиной этого, я наконец-то дошел до того, что выглядит как , ошибка появляется только в том случае, если nrow(df) является четным числом? Я несколько сомневаюсь, что это действительно объяснение, но в этот момент я решил задать здесь вопрос: в чем причина? Единственная связанная проблема, которую я обнаружил, была здесь , но я не уверен, что это та же проблема?

Редактировать:

Ошибка не повышается, если я заменяю median на min или max!

MRE:

library(dplyr)
df <- data.frame(ID = 1:7,
                 Group = c(1, 1, 1, 2, 2, 2, 1),
                 val1 = c(1, NA, 3, 2, 2, 3, 2),
                 val2 = c(2, 2, 2, NA, 1, 3, 2))

df %>%
  group_by(Group) %>% 
  mutate_at(vars(-group_cols()), ~coalesce(., median(.,na.rm=TRUE))) %>% 
  ungroup()

Повышает:

Ошибка: Аргумент 2 должен быть целым вектором, а не двойным вектором

Но если я удалю последнюю строку (или три последние строки):

df[1:6, ] %>%
  group_by(Group) %>% 
  mutate_at(vars(-group_cols()), ~coalesce(., median(.,na.rm=TRUE))) %>% 
  ungroup()

Это работает .... !! ?

PS
Использование ifelse(is.na(.)... вместо coalesce работает также независимо от количества строк:

df %>%
group_by(Group) %>% 
mutate_at(vars(-group_cols()), ~ifelse(is.na(.), median(., na.rm = TRUE), .)) %>% 
ungroup()

PPS Ошибка также возникает при использовании mean вместо median

1 Ответ

2 голосов
/ 07 марта 2020

Документация median гласит:

Метод по умолчанию возвращает объект длины один того же типа, что и x, за исключением случаев, когда x является логическим или целым числом четной длины, когда результат будет double. "

И ошибка, которую вы видите, не выдается, если df $ ID имеет значение as.numeric. Предполагает, что coalesce запутывается классом df$ID.

library(dplyr)
df <- data.frame(ID = 1:7,
  Group = c(1, 1, 1, 2, 2, 2, 1),
  val1 = c(1, NA, 3, 2, 2, 3, 2),
  val2 = c(2, 2, 2, NA, 1, 3, 2))

# convert ID to numeric
df$ID <- as.numeric(df$ID)

df %>%
  group_by(Group) %>% 
  mutate_at(vars(-group_cols()), ~coalesce(., median(.,na.rm=TRUE))) %>% 
  ungroup()

Обратите внимание также, как class идентификатора может варьироваться в зависимости от того, как он вводится:

IDa = 1:7
class(IDa)

IDb = c(1,2,3,4,5,6,7)
class(IDb)

IDc = c(1L,2L,3L,4L,5L,6L,7L)
class(IDc)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...