是否存在比先pivot_longer再pivot_wider更简便的数据转换方案?
数据重塑的简化实现方案
问题场景
你有如下结构的原始数据集:
region year people cash 0 area1 2020 32 29 1 area1 2021 43 40 2 area2 2020 51 23 3 area2 2021 99 98
想要转换成这种格式:
variable area1 area2 year 0 people 32 51 2020 1 cash 29 23 2020 2 people 43 99 2021 3 cash 40 98 2021
目前已经用这段代码实现,但觉得先转长再转宽的步骤有点繁琐:
data_long <- data %>% pivot_longer(-c(region,year)) %>% pivot_wider(names_from = region) %>% select(variable, area1, area2, year)
下面给你几个更简便的替代方案:
简化方案
1. 优化tidyverse链式代码
可以去掉中间变量,直接用链式操作完成,还可以用relocate替代select,更贴合“调整列顺序”的语义:
data %>% pivot_longer(-c(region, year), names_to = "variable") %>% pivot_wider(names_from = region, values_from = value) %>% relocate(variable, area1, area2, year)
这段代码和你的原逻辑一致,但写法更紧凑,没有多余的中间变量,可读性也更好。
2. 用data.table一步完成重塑
如果可以使用data.table包,能通过dcast和melt的组合实现更直接的转换,步骤更集中:
library(data.table) setDT(data) dcast(data, year + variable ~ region, value.var = c("people", "cash")) %>% melt(id.vars = "year", measure.vars = patterns("people", "cash"), variable.name = "variable", value.name = c("area1", "area2")) %>% setcolorder(c("variable", "area1", "area2", "year"))
这种方式适合熟悉data.table语法的场景,代码整体更凝练。
3. 极简tidyverse写法(保留核心逻辑)
其实你的原逻辑本身已经很清晰,只是可以去掉中间变量,直接链式执行,代码会简洁很多:
data %>% pivot_longer(-c(region, year)) %>% pivot_wider(names_from = region) %>% select(variable, area1, area2, year)
去掉data_long中间变量后,代码更清爽,逻辑也一目了然。
内容的提问来源于stack exchange,提问作者bajun65537
相关产品推荐
相关产品推荐

