R语言高效堆叠数据框并批量修改年份列的方法
问题描述
现有存储2008年美国各州选举结果的数据框p08,其中DemStatus字段1代表支持民主党、0代表支持共和党。需将每个州的选举结果延续至选举后四年(2008-2011年),目前通过手动复制数据框并修改YEAR字段实现,但因数据覆盖90年代至2020年,操作繁琐,求更高效的实现方法。原手动实现代码如下:
p08=structure(list(STATE = c("Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "Dist. of Col.", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"), YEAR = c(2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008), DemStatus = c(0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0)), row.names = 10:60, class = "data.frame") party09=p08 party09$YEAR=2009 party10=p08 party10$YEAR=2010 party11=p08 party11$YEAR=2011 party08_11 = bind_rows(p08,party09,party10,party11)
高效解决方案
方法1:Tidyverse工具链(推荐,易扩展)
利用tidyr和dplyr的组合函数,无需手动复制数据框,代码简洁且支持批量处理多选举年。
单选举年(2008)处理
方式A:用uncount生成重复行后赋值年份
library(tidyverse) party08_11 <- p08 %>% uncount(4) %>% # 每个州的记录重复4次,对应2008-2011四年 group_by(STATE) %>% mutate(YEAR = 2008:(2008 + n() - 1)) %>% ungroup()
方式B:用expand生成年份序列后关联原数据
library(tidyverse) party08_11 <- p08 %>% select(-YEAR) %>% # 移除原数据中固定的2008年份 group_by(STATE, DemStatus) %>% expand(YEAR = 2008:2011) %>% # 生成目标年份序列 ungroup()
方法2:Base R实现(无需额外包)
仅用基础R函数完成,适合不想加载第三方包的场景:
# 生成对应四年的年份序列,每个年份重复nrow(p08)次 year_sequence <- rep(2008:2011, each = nrow(p08)) # 重复原数据4次,替换YEAR字段 party08_11 <- transform(p08[rep(1:nrow(p08), 4), ], YEAR = year_sequence)
扩展:批量处理多选举年份(1990-2020)
如果有多个选举年的数据框(如p96、p00、p04等),可以先合并所有选举年数据,再批量生成后续年份:
library(tidyverse) # 假设已有多个选举年的数据框,先合并为总数据 all_election_data <- bind_rows(p96, p00, p04, p08, p12, p16, p20) # 为每个选举年生成后续3年的数据(共4年:选举年+后3年) expanded_full_data <- all_election_data %>% group_by(STATE, DemStatus, YEAR) %>% expand(YEAR = YEAR:(YEAR + 3)) %>% ungroup()
内容的提问来源于stack exchange,提问作者bandcar
相关产品推荐
相关产品推荐

