如何用R的dplyr包基于字符型月份变量创建季节变量?
解决dplyr创建season变量的报错问题
首先,咱们来拆解下你遇到的报错原因:你写的month[1:3]是在提取数据集中前3行的month值,得到的是一个长度为3的向量,但你的数据集有100798行,mutate要求新生成的列必须和原数据行数一致,所以就出现了长度不匹配的错误。
正确的思路应该是逐行判断每个month值是否属于某个季节的月份范围,而不是提取子集。下面给你两种实用的解决方法,都基于dplyr实现:
方法一:用case_when(推荐,可读性更强)
case_when是dplyr里替代嵌套ifelse的绝佳工具,每个条件对应一个结果,逻辑清晰易懂:
如果你的month是数字形式的字符(比如"1"、"2"..."12")
library(dplyr) data <- data %>% mutate(season = case_when( month %in% c("1", "2", "3") ~ "Winter", month %in% c("4", "5", "6") ~ "Spring", month %in% c("7", "8", "9") ~ "Summer", month %in% c("10", "11", "12") ~ "Fall", TRUE ~ NA_character_ # 处理不属于1-12的异常值 ))
如果你的month是英文月份名称(比如"January"、"February")
只需要调整判断的月份向量即可:
data <- data %>% mutate(season = case_when( month %in% c("January", "February", "March") ~ "Winter", month %in% c("April", "May", "June") ~ "Spring", month %in% c("July", "August", "September") ~ "Summer", month %in% c("October", "November", "December") ~ "Fall", TRUE ~ NA_character_ ))
方法二:修正嵌套ifelse的写法
如果你还是想用ifelse,需要把每个条件改成判断当前行的month是否在目标集合里,而不是提取子集:
data <- data %>% mutate(season = ifelse(month %in% c("1","2","3"), "Winter", ifelse(month %in% c("4","5","6"), "Spring", ifelse(month %in% c("7","8","9"), "Summer", ifelse(month %in% c("10","11","12"), "Fall", NA)))))
不过这种嵌套写法在条件增多时会变得臃肿,还是更推荐用case_when来保持代码的整洁性。
内容的提问来源于stack exchange,提问作者newbie14
相关产品推荐
相关产品推荐

