使用循环与dplyr重命名列表中数据框列名失败,求修正方法
问题描述
我有一个包含多个data frame的列表list_prices_python,以及一个列名向量name_prices_python,希望通过循环将每个data frame中的TR.CLOSEPRICE列重命名为name_prices_python中对应的元素。但执行代码后,列名被设置为循环变量"i",不符合预期,请问需要如何修改?
示例数据:
list_prices_python[[1]] DATE Instrument TR.CLOSEPRICE <date> <chr> <dbl> 1 2009-01-01 NA 356. 2 2009-01-02 NA 356. 3 2009-01-03 NA 356. 4 2009-01-04 NA 357. 5 2009-01-05 NA 357. 6 2009-01-06 NA 357. 7 2009-01-07 NA 357. 8 2009-01-08 NA 357. 9 2009-01-09 NA 357. 10 2009-01-10 NA 357. name_prices_python [1] "ASF.CN" "CAR_p.CN" "CIC.CN" "CLM.CN" "CON.CN" "CTV.CN" "DVI_p.CN" "FGN.CN" "GNO.CN" "MYG.CN" [11] "ORB.CN" "PMG.CN" "RPI.CN" "TPL.CN" "TRR.CN"
执行的代码:
for(i in name_prices_python){ list_prices_python[[i]] %>% dplyr::rename(i = `TR.CLOSEPRICE`) -> list_prices_python[[i]] }
错误结果:
# A tibble: 4,944 x 3 DATE Instrument i <date> <chr> <dbl> 1 2009-01-01 NA 356. 2 2009-01-02 NA 356. 3 2009-01-03 NA 356. 4 2009-01-04 NA 357. 5 2009-01-05 NA 357. 6 2009-01-06 NA 357. 7 2009-01-07 NA 357. 8 2009-01-08 NA 357. 9 2009-01-09 NA 357. 10 2009-01-10 NA 357.
问题原因
dplyr::rename()中直接写i = TR.CLOSEPRICE``时,左侧的i会被当作字面量字符串处理,而不是循环变量i的实际值,因此列名被设置为"i"而非目标字符串。
解决方案
方案1:使用tidyeval动态赋值(dplyr方式)
利用!!解引用变量,结合:=实现动态命名:
for(i in name_prices_python){ list_prices_python[[i]] <- list_prices_python[[i]] %>% dplyr::rename(!!i := `TR.CLOSEPRICE`) }
!!i会将循环变量i的实际值(如"ASF.CN")替换进去:=是dplyr中用于动态列名赋值的操作符
方案2:使用rename_with函数(更简洁的dplyr方式)
rename_with可以直接指定列名的转换规则:
for(i in name_prices_python){ list_prices_python[[i]] <- list_prices_python[[i]] %>% dplyr::rename_with(~i, `TR.CLOSEPRICE`) }
- 第一个参数
~i表示将目标列重命名为变量i的值 - 第二个参数指定要重命名的列
TR.CLOSEPRICE
方案3:Base R实现(无需dplyr)
如果不想依赖dplyr,可以直接修改列名:
# 按索引循环,确保列表元素与列名向量位置对应 for(idx in seq_along(name_prices_python)){ df <- list_prices_python[[idx]] col_idx <- which(colnames(df) == "TR.CLOSEPRICE") colnames(df)[col_idx] <- name_prices_python[idx] list_prices_python[[idx]] <- df }
这种方式更高效,且避免了tidyeval的语法,适合习惯Base R的用户。
内容的提问来源于stack exchange,提问作者Mick
相关产品推荐
相关产品推荐

