You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用dcast保留多年份世界银行发展数据?

问题描述

手里有一份2016-2020年世界银行发展数据的CSV表格,结构包含Country.Code、Series.Name及各年份数值列。原本只用到2020年数据,但部分变量缺失,需要保留所有年份数据,想把表格转成以Country.Code为行、Series.Name为列,同时保留2016-2020年所有数据的宽表。

尝试过的代码及错误

最初用这段代码只能保留2020年数据:

ControlM <- dcast(Control, Country.Code ~ Series.Name)

尝试指定value.var包含所有年份列时触发错误:

ControlM <- dcast(
  Control, 
  Country.Code ~ Series.Name, 
  value.var = c("2016", "2017", "2018", "2019", "2020")
)

错误信息:

Error in if (!(value.var %in% names(data))) { : 
  the condition has length > 1

试过转成data.table、设置value.var = NULL等方法,均无效。

数据样本

dput(head(Control))输出:

structure(list(Country.Name = c("Argentina", "Argentina", "Argentina", 
"Argentina", "Argentina", "Armenia"), Country.Code = c("ARG", 
"ARG", "ARG", "ARG", "ARG", "ARM"), Series.Name = c("Gini index", 
"Trade (% of GDP)", "Population density (people per sq. km of land area)", 
"Population, total", "Educational attainment, at least completed post-secondary, population 25+, total (%) (cumulative)", 
"Gini index"), Series.Code = c("SI.POV.GINI", "NE.TRD.GNFS.ZS", 
"EN.POP.DNST", "SP.POP.TOTL", "SE.SEC.CUAT.PO.ZS", "SI.POV.GINI"
), `2016` = c("42", "26.0938878488799", "15.9281350828921", "43590368", 
"..", "32.5"), `2017` = c("41.1", "25.2896011376779", "16.0941907925267", 
"44044811", "..", "33.6"), `2018` = c("41.3", "30.7625359549926", 
"16.2585100979651", "44494502", "..", "34.4"), `2019` = c("42.9", 
"32.6306150458499", "16.4208266190179", "44938712", "..", "29.9"
), `2020` = c("42.3", "30.2197998857878", "16.580892611147", 
"45376763", "..", "25.2")), row.names = c(NA, -6L), class = c("data.table", 
"data.frame"), .internal.selfref = <pointer: 0x00000193c0bd5930>)
解决方案

不管用data.table还是reshape2的dcast,都不能直接给value.var传多个列名。正确思路是先把数据转成长格式(年份作为单独一列),再转成宽格式,把年份和Series.Name组合成列名。

方法1:使用data.table(效率更高)

# 加载data.table包
library(data.table)

# 转成长格式:将2016-2020列转成Year和Value两列
Control_long <- melt(Control, 
                     id.vars = c("Country.Code", "Series.Name"),
                     measure.vars = c("2016", "2017", "2018", "2019", "2020"),
                     variable.name = "Year",
                     value.name = "Value")

# 转成宽格式:Country.Code为行,Year和Series.Name组合为列
ControlM <- dcast(Control_long, 
                  Country.Code ~ Year + Series.Name,
                  value.var = "Value")

方法2:使用reshape2包

# 加载reshape2包
library(reshape2)

# 转成长格式
Control_long <- melt(Control, 
                     id.vars = c("Country.Code", "Series.Name"),
                     measure.vars = c("2016", "2017", "2018", "2019", "2020"),
                     variable.name = "Year",
                     value.name = "Value")

# 转成宽格式
ControlM <- dcast(Control_long, 
                  Country.Code ~ Year + Series.Name,
                  value.var = "Value")

额外处理:替换缺失值标记

数据里的".."是缺失值标记,可以在转格式前后替换成NA:

# 替换所有".."为NA
Control[Control == ".."] <- NA
# 可选:将Value列转为数值型
Control_long[, Value := as.numeric(Value)]

内容的提问来源于stack exchange,提问作者Jana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 18:15:59