Измените столбец, чтобы получить минимум значений не-NA в группе, когда не можете использовать group_by - PullRequest
0 голосов
/ 10 ноября 2019

Я пытаюсь взять столбец данных, который имеет сочетание значений и NA, и заменить значения минимальными значениями в группе. Проблема в том, что я не нашел способ использовать group_by в этом случае, потому что в наборе данных нет уникальной группировки.

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

Я попробовал group_by, но понял, что это не будет работать, как описано выше. Затем я попробовал if_else, но я думаю, что это не удалось, потому что is.numeric не векторизовано.

Последний кадр данных - это то, чего я пытаюсь достичь.

Пример данных

library(dplyr)

# Initial
initial <- structure(list(dates = structure(c(17532, 17539, 17546, 17553, 
                                             17560, 17567, 17574, 17581, 17588, 17595, 17602, 17609, 17616, 
                                             17623, 17630, 17637, 17644, 17651, 17658, 17665, 17672, 17679
), class = "Date"), values = c(10, 10, 10, 11, NA, NA, NA, NA, 
                               NA, 20, 20, 21, 22, NA, NA, NA, NA, NA, 30, 30, 31, NA)), class = "data.frame", row.names = c(NA, 
                                                                                                                             -22L))
# Final
final <- structure(list(dates = structure(c(17532, 17539, 17546, 17553, 
                                              17560, 17567, 17574, 17581, 17588, 17595, 17602, 17609, 17616, 
                                              17623, 17630, 17637, 17644, 17651, 17658, 17665, 17672, 17679
), class = "Date"), values = c(10, 10, 10, 11, NA, NA, NA, NA, 
                               NA, 20, 20, 21, 22, NA, NA, NA, NA, NA, 30, 30, 31, NA), desired = c(10, 
                                                                                                    10, 10, 10, NA, NA, NA, NA, NA, 20, 20, 20, 20, NA, NA, NA, NA, 
                                                                                                    NA, 30, 30, 30, NA)), class = "data.frame", row.names = c(NA, 
                                                                                                                                                              -22L))

Эта и другие попытки не сработали. Я подозреваю, потому что is.numeric не векторизован. Я также попробовал некоторые версии mutate_at, но не смог заставить это работать.

# Did not work
initial %>%
  mutate(desired = ifelse(is.numeric(values), ifelse(is.numeric(lag(values)), lag(values), values), values))

1 Ответ

0 голосов
/ 10 ноября 2019

Мы можем использовать data.table::rleid для создания групп и выбрать min значение из каждой.

library(dplyr)

initial %>%
  group_by(group = data.table::rleid(is.na(values))) %>%
  mutate(ans = min(values)) %>% 
  ungroup() %>%
  select(-group)

# A tibble: 22 x 3
#   dates      values   ans
#   <date>      <dbl> <dbl>
# 1 2018-01-01     10    10
# 2 2018-01-08     10    10
# 3 2018-01-15     10    10
# 4 2018-01-22     11    10
# 5 2018-01-29     NA    NA
# 6 2018-02-05     NA    NA
# 7 2018-02-12     NA    NA
# 8 2018-02-19     NA    NA
# 9 2018-02-26     NA    NA
#10 2018-03-05     20    20
# … with 12 more rows

Для чисто dplyr решения мы можем заменить group_by оператор на

group_by(group = cumsum(is.na(values) != lag(is.na(values), default = FALSE))) %>%
...