R语言:如何基于另一DataFrame的列值为目标DataFrame批量新增列
我懂你的困扰啦——你想把df2里的年份作为新列名批量加到df中,每列初始值设为0,但循环里直接用变量名的话,R总是把列名变成"variable"或者报错,根本取不到df2里的实际年份值对吧?
问题出在动态列名的解析方式上:R的$操作符和直接在mutate里写变量名时,不会自动解析变量里的内容,而是直接把变量名当成列名。得用能识别动态值的方法来处理,下面给你几种可行的方案:
方法一:Base R 循环实现
先把df2里的年份提取成字符向量,然后用[[操作符(它能解析变量里的实际值)来添加列:
# 提取df2的年份并转为字符型(列名最好是字符格式) year_cols <- as.character(df2$Años) # 循环添加每一列,初始值为0 for (year in year_cols) { df[[year]] <- 0 }
这里用df[[year]]而不是df$year,因为[[会先读取year变量里的内容(比如"2007"),再作为列名创建新列,完美解决你之前列名不对的问题。
方法二:dplyr 简洁实现(推荐)
如果用tidyverse的dplyr,可以不用循环,一次性生成所有列,代码更简洁高效:
library(dplyr) year_cols <- as.character(df2$Años) # 方式1:用across + all_of df <- df %>% mutate(across(all_of(year_cols), ~0)) # 方式2:用set_names + !!!(非标准求值) df <- df %>% mutate(!!!set_names(rep(0, length(year_cols)), year_cols))
all_of(year_cols)会把字符向量里的年份转换成列名,across对这些列统一赋值为0(不存在的列会自动创建)- 第二种方式里,
set_names给重复的0向量加上年份作为名字,!!!把这个带名向量拆成2007=0, 2008=0...的形式,让mutate识别为新列赋值。
你之前代码的问题
你之前尝试的df$df2[indice,]或者mutate(df2[indice,]=0),R会把df2[indice,]这个表达式直接当成列名(而不是提取里面的年份值),所以要么报错,要么生成奇怪的列名。必须先把年份提取成独立的字符向量,再用支持动态解析的方法来指定列名。
最终结果
运行上面的代码后,你的df就会变成你想要的样子:
ProyectoID Nombre Contratado 2007 2008 2009 2010
1 D0000052 D.O.Línea Alta Velocidad Vitor 3606443.81 0 0 0 0
2 X0000100 AT Conservación Red Foral Bizk 2218057.00 0 0 0 0
3 D0000062 D.O. Alta velocidad Hernialde- 1545665.21 0 0 0 0
4 CABL2016 Proyectos y D.O. de Abastecimi 1160413.00 0 0 0 0
5 X0000120 Bloque proyectos y obras STI 2 1063783.11 0 0 0 0
内容的提问来源于stack exchange,提问作者kintela

