r - case_when 在一个实例中起作用,而不是在另一个实例中
问题描述
我正在尝试按季度汇总数据。但是,季度不遵循正常季度。我的季度从十二月开始。
我可以使用以下代码将数据分解为季度:
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
现在我尝试更改季度细分,因此季度从 12 月开始,例如
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
为什么我会得到 NA?
解决方案
简短的回答:
使用%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
长答案
由于选择的数字和 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
scase_when
推荐阅读
- python - 如何使用 python 在 MongoDB 中创建模式?
- javascript - 如何在javascript文件中获取城市和首都的输入数组?
- plotly - 使用下拉列表选择加载 Plotly Dash 数据表时出现问题
- php - 增加星号和零的打印模式
- c++ - 在计算数字总和时,如果分配变量的范围超出,则给出一些数值。该值是什么意思?
- gatsby - Gatsby sourceNode 不适用于 GraphQL 参数
- python - 如何在日期时间类型的对象处修复 Python 不是 JSON 可序列化错误
- c++ - Opengl sws_scale 不工作(分段错误)
- angular - MatSidenav 和 MatDrawer 有什么区别?
- python - “str”对象没有属性“dropna”