R语言if-else语句问题:dec列全为0的原因排查
问题分析与解决
核心原因
你代码里的内层循环用了seq_along(2:13),这个函数会生成输入向量的索引序列——2:13是包含12个元素的向量,所以seq_along(2:13)实际生成的是1:12,而非你预期的2:13。这导致j的取值永远到不了13,对应dec列的判断逻辑else if(j==13)永远不会执行,所以dec列始终全为0。
修正后的代码
把内层循环的seq_along(2:13)改成2:13即可:
mc_mon <- seq(as.Date("2013/04/01"), as.Date("2022-07-01"), by="month") mc_mon <- as.data.frame(mc_mon) month_indicator_mat <- data.frame(mc_mon$mc_mon, jan=vector(mode = "integer", length = nrow(mc_mon)), feb=vector(mode = "integer", length = nrow(mc_mon)), mar=vector(mode = "integer", length = nrow(mc_mon)), apr=vector(mode = "integer", length = nrow(mc_mon)), may=vector(mode = "integer", length = nrow(mc_mon)), jun=vector(mode = "integer", length = nrow(mc_mon)), jul=vector(mode = "integer", length = nrow(mc_mon)), aug=vector(mode = "integer", length = nrow(mc_mon)), sep=vector(mode = "integer", length = nrow(mc_mon)), oct=vector(mode = "integer", length = nrow(mc_mon)), nov=vector(mode = "integer", length = nrow(mc_mon)), dec=vector(mode = "integer", length = nrow(mc_mon))) for(i in seq_along(1:nrow(month_indicator_mat))){ # 将seq_along(2:13)替换为2:13 for(j in 2:13){ if(j==2){if(substr(month_indicator_mat[i,1],6,7) == "01") {month_indicator_mat[i,j] <- 1}} else if(j==3){if(substr(month_indicator_mat[i,1],6,7) == "02") {month_indicator_mat[i,j] <- 1}} else if(j==4){if(substr(month_indicator_mat[i,1],6,7) == "03") {month_indicator_mat[i,j] <- 1}} else if(j==5){if(substr(month_indicator_mat[i,1],6,7) == "04") {month_indicator_mat[i,j] <- 1}} else if(j==6){if(substr(month_indicator_mat[i,1],6,7) == "05") {month_indicator_mat[i,j] <- 1}} else if(j==7){if(substr(month_indicator_mat[i,1],6,7) == "06") {month_indicator_mat[i,j] <- 1}} else if(j==8){if(substr(month_indicator_mat[i,1],6,7) == "07") {month_indicator_mat[i,j] <- 1}} else if(j==9){if(substr(month_indicator_mat[i,1],6,7) == "08") {month_indicator_mat[i,j] <- 1}} else if(j==10){if(substr(month_indicator_mat[i,1],6,7) == "09") {month_indicator_mat[i,j] <- 1}} else if(j==11){if(substr(month_indicator_mat[i,1],6,7) == "10") {month_indicator_mat[i,j] <- 1}} else if(j==12){if(substr(month_indicator_mat[i,1],6,7) == "11") {month_indicator_mat[i,j] <- 1}} else if(j==13){if(substr(month_indicator_mat[i,1],6,7) == "12") {month_indicator_mat[i,j] <- 1}} } }
更简洁的实现方式
嵌套循环不是R的最优写法,推荐用向量操作和内置函数简化代码,效率更高:
library(lubridate) library(dplyr) # 生成日期序列 mc_mon <- tibble(date = seq(as.Date("2013/04/01"), as.Date("2022-07-01"), by = "month")) # 提取月份并批量生成0-1标记列 mc_mon <- mc_mon %>% mutate(month_num = month(date)) %>% mutate(across(1:12, ~as.integer(month_num == .x), .names = "{month.abb[.x]}")) %>% select(-month_num)
这段代码用lubridate::month()提取月份数字,再通过dplyr::across()批量生成各月份的0-1标记,代码简洁易维护,也避免了循环带来的逻辑错误。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

