R语言嵌套for循环索引问题:platform_datatest宽表转长表索引设置求助
原有循环的修复方案
你代码里缺失的索引k直接按以下公式计算即可:
k <- (j - 1) * 30 + i
这个公式的逻辑是每个候选人占连续30行,第j位候选人的起始行是前j-1位占用的总行数(也就是(j-1)*30)加1,恰好对应你要的1-30行是第1位候选人、31-60是第2位的要求。
另外注意你初始化空数据集时不要写死长度为60,要适配候选人总数,修改初始化逻辑:
total_row <- 30 * nrow(platform_datatest) platform_settest <- data.frame(name = rep(NA, length = total_row), state = rep(NA, length = total_row), year = rep(NA, length = total_row), topic = rep(NA, length = total_row), title = rep(NA, length = total_row), text = rep(NA, length = total_row))
修正后的完整循环代码如下:
# 初始化适配总长度的空数据集 total_row <- 30 * nrow(platform_datatest) platform_settest <- data.frame(name = rep(NA, length = total_row), state = rep(NA, length = total_row), year = rep(NA, length = total_row), topic = rep(NA, length = total_row), title = rep(NA, length = total_row), text = rep(NA, length = total_row)) for (j in 1:nrow(platform_datatest)){ # 遍历所有候选人 for(i in 1:30){ # 遍历每个候选人的30项纲领 # 提取候选人基础信息 name <- platform_datatest[j, 1] state <- platform_datatest[j, 3] year <- platform_datatest[j, 4] # 生成对应纲领的列名 topic_col <- paste0("Q24A.1_", i) title_col <- paste0("Q24A.2_", i, "_1") text_col <- paste0("Q24A.3_", i, "_1") # 计算目标行索引 k <- (j - 1) * 30 + i # 赋值 platform_settest[k, 1] <- name platform_settest[k, 2] <- state platform_settest[k, 3] <- year platform_settest[k, 4] <- platform_datatest[j, topic_col] platform_settest[k, 5] <- platform_datatest[j, title_col] platform_settest[k, 6] <- platform_datatest[j, text_col] } }
更高效的长表转换方案
R中针对宽转长的需求,不用手动写循环实现,用tidyr包的pivot_longer函数可以更简洁地完成,代码容错率更高:
library(tidyr) library(dplyr) platform_settest <- platform_datatest %>% # 选择需要保留的基础信息列,以及所有纲领相关列 select(name = 1, state = 3, year = 4, starts_with("Q24A.")) %>% # 宽转长,按纲领序号分组 pivot_longer( cols = starts_with("Q24A."), names_to = c(".value", "i"), names_pattern = "Q24A\\.([123])_(\\d+)" ) %>% # 重命名对应列 rename(topic = `1`, title = `2`, text = `3`) %>% # 去除不需要的序号列(可选) select(-i)
如果列名匹配规则需要调整,可以根据你实际的列名修改names_pattern里的正则表达式即可。
内容的提问来源于stack exchange,提问作者IL425
相关产品推荐
相关产品推荐

