按每周各天次数重复行程行的R代码异常排查
问题:按周几数值重复行程数据行并修正全零行问题
需求与问题描述
- 需求:根据数据集15-21列(对应周一到周日)的数值,将每行数据重复对应次数,生成的新行仅保留对应天数为1,其余周几列设为0,其余列保持不变。例如输入周几列数值
[0,2,1,0,1,2,0],需生成6行,每行分别对应周二2次、周三1次、周五1次、周六2次,每行仅对应天数为1。 - 问题:现有R代码处理后,部分行生成全零周几列,重复次数正确但内容不符合预期。
原代码
duplicate_accordingto_value <- function(row) { sum_cols <- sum(row[15:21] > 0, na.rm = TRUE) if (sum_cols == 0) { duplicated_obs <- row duplicated_observation[15:21] <- 1 return(rbind(row, duplicated_observation)) } else { duplicated_observations <- list() indices <- which(row[15:21] > 0) for (i in 1:sum_cols) { new_observation <- row new_observation[15:21] <- 0 if (i <= length(indexes)) { new_observation[15 + indices[i] - 1] <- 1 } duplicated_observations[[i]] <- new_observation } return(do.call(rbind, duplicated_observations)) } } # Apply the function to all the rows sfu2 <- sfu2 %>% rowwise() %>% do({ observation <- as.data.frame(.) duplicate_accordingto_value(observation) }) %>% ungroup()
问题分析
- 变量名拼写错误:代码中使用了未定义的
indexes变量,正确变量名应为indices,导致if条件始终不成立,无法将对应周几列设为1,生成全零行。 - 核心逻辑错误:
sum_cols计算的是"有非零值的天数数量",但实际需求是"所有天数数值的总和"(比如示例中2+1+1+2=6),原函数的重复次数逻辑完全错误。 - 全零分支逻辑混乱:当所有周几列都是0时,原代码返回两行且其中一行设置全1,不符合需求逻辑(若无需保留此类行,应直接返回空或原行,需根据实际场景调整)。
修正后的代码
# 定义处理单行的函数 duplicate_accordingto_value <- function(row) { # 提取周几列的数值 day_values <- unlist(row[15:21]) # 计算每个天数需要重复的次数,生成索引向量 day_indices <- rep(1:7, times = day_values) # 如果没有需要重复的天数,返回原行或空(根据需求调整) if (length(day_indices) == 0) { return(row) # 若无需保留全零行,可改为 return(NULL) } # 生成重复后的行列表 duplicated_list <- lapply(day_indices, function(idx) { new_row <- row # 重置所有周几列为0 new_row[15:21] <- 0 # 将对应天数设为1 new_row[15 + idx - 1] <- 1 return(new_row) }) # 合并为数据框 do.call(rbind, duplicated_list) } # 应用函数到所有行(改用pmap更高效,避免rowwise的性能问题) library(purrr) sfu2 <- sfu2 %>% split(1:nrow(.)) %>% map_dfr(duplicate_accordingto_value)
说明
- 修正后的函数通过
rep(1:7, times = day_values)直接生成每个天数需要重复的索引,准确匹配需求中的重复次数。 - 使用
purrr的map_dfr替代rowwise()+do,处理大数据集时性能更优。 - 全零行分支可根据实际需求调整:若无需保留全零周几列的行,将
return(row)改为return(NULL)即可。
内容的提问来源于stack exchange,提问作者David Lopez
相关产品推荐
相关产品推荐

