case_when работает в одном случае, а не в другом - PullRequest
0 голосов
/ 20 мая 2019

Я пытаюсь обобщить данные за квартал. Однако кварталы не следуют нормальным кварталам. Мой квартал начинается в декабре.

Я могу разбить данные на кварталы, используя следующий код:

require(tidyverse)

# generate dummy data
data <- data.frame(value = runif(12, min = 10000, max = 12000),
                   month = 1:12,
                   stringsAsFactors = F)

qtr <- data %>% 
  mutate(quarter = case_when(month == 1:3 ~ 1,
                             month == 4:6 ~ 2,
                             month == 7:9 ~ 3,
                             month == 9:12 ~ 4))

Результаты как и ожидалось:

       value month quarter
1  11959.56     1       1
2  10389.29     2       1
3  10731.31     3       1
4  10433.61     4       2
5  11969.98     5       2
6  10240.25     6       2
7  11415.40     7       3
8  10942.18     8       3
9  11114.58     9       3
10 11109.37    10       4
11 11448.45    11       4
12 10940.48    12       4

Теперь я пытаюсь изменить квартальную разбивку, чтобы кварталы начинались в декабре, например,

qtr <- data %>% 
      mutate(quarter = case_when(month == 1:2 ~ 1,
                             month == 3:5 ~ 2,
                             month == 6:8 ~ 3,
                             month == 9:11 ~ 4,
                             month == 12 ~ 1))

И я получаю:

      value month quarter
1  11959.56     1       1
2  10389.29     2       1
3  10731.31     3      NA
4  10433.61     4      NA
5  11969.98     5      NA
6  10240.25     6      NA
7  11415.40     7      NA
8  10942.18     8      NA
9  11114.58     9      NA
10 11109.37    10      NA
11 11448.45    11      NA
12 10940.48    12       1

Почему я получаю АН?

1 Ответ

2 голосов
/ 20 мая 2019

Краткий ответ:

Используйте %in% вместо ==, так как вы хотите сравнить несколько значений

library(dplyr)

data %>% 
   mutate(quarter = case_when(month %in% c(1:2, 12) ~ 1,
                              month %in% 3:5 ~ 2,
                              month %in% 6:8 ~ 3,
                              month %in% 9:11 ~ 4))

#      value month quarter
#1  11216.52     1       1
#2  10767.37     2       1
#3  10631.57     3       2
#4  11906.64     4       2
#5  11575.19     5       2
#6  11403.56     6       3
#7  10315.16     7       3
#8  11631.13     8       3
#9  11083.61     9       4
#10 11755.59    10       4
#11 10247.68    11       4
#12 10485.54    12       1

LongОтвет

Первый вариант «работает» случайно из-за выбранных чисел и свойства переработки в R.

Например, рассмотрим этот случай

1:10 == 4:6
# [1] FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE

Предупреждающее сообщение: В 1:10 == 4: 6: длинная длина объекта не кратна короткой длине объекта

На самом деле здесь 4:6 перерабатывается и становится

a1 <- rep(4:6, length.out = 10)
a1
#[1] 4 5 6 4 5 6 4 5 6 4

и теперь это сравнивается с

a2 <- 1:10
a2
# [1]  1  2  3  4  5  6  7  8  9 10

элемент за элементом.Проверьте значения в позиции 4:6 в a1 и a2

a1[4:6]
#[1] 4 5 6
a2[4:6]
#[1] 4 5 6

, они оба одинаковы, и, следовательно, вы получите значения TRUE в этих позициях при сравнении в case_when.То же самое происходит в остальных случаях с первой попытки, и вы думаете, что это работает.

Он не будет работать должным образом, даже если вы поменяете один номер здесь или там.Например,

data %>% 
  mutate(quarter = case_when(month == 1:2 ~ 1,
                             month == 3:6 ~ 2,
                             month == 7:9 ~ 3,
                             month == 9:12 ~ 4))

#      value month quarter
#1  11436.83     1       1
#2  10524.27     2       1
#3  10110.57     3      NA
#4  11755.68     4      NA
#5  10757.70     5      NA
#6  10203.56     6      NA
#7  11346.90     7       3
#8  10308.79     8       3
#9  10328.54     9       3
#10 10732.88    10       4
#11 11150.69    11       4
#12 10990.28    12       4

Для вашего второго случая 3:5 перерабатывается и сравнивается по элементам

a3 <- rep(3:5, length.out = 10)

a2 == a3
# [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

Поскольку не было совпадений, все значения равны FALSE, и вы получаетеNA с в case_when

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...