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

R语言:使用paste0、get与for循环批量处理列的实现问题

数据结构说明

以下是我的数据结构:
(数字代表不同种类的水果;CT1_100_FQ、CT1_100_AM、CT1_100_SS为预设数值)

library(plyr); library(dplyr)
library(magrittr)
library(ExclusionTable)
library(lubridate)

totfr <- list('095',
              '096',
              '097',
              '098',
              '099',
              '100',
              '101',
              '102',
              '103',
              '104',
              '105',
              '106')

hgi <- list('096',
            '097',
            '099')
mgi <- list('100',
            '101',
            '105')
lgi <- list('095',
            '098',
            '102',
            '103',
            '104',
            '106')

hgl <- list('097',
            '099',
            '104',
            '105')
mgl <- list('096',
            '100')
lgl <- list('095',
            '098',
            '101',
            '102',
            '103',
            '106')

classification <- list(
                    totfr,
                    hgi,
                    mgi,
                    lgi,
                    hgl,
                    mgl,
                    lgl
                    )

names(classification) <- c(
                           "totfr",
                           "hgi",
                           "mgi",
                           "lgi",
                           "hgl",
                           "mgl",
                           "lgl"
                           )
现有代码
ct <-
  ct %>%
  for (i in 1:length(classification))
    for (j in 1:length(classification[[i]])){
                            get(paste("ct$CT1_F", classification[[i]][j], sep="")) <- get(paste("ct$CT1_F", paste0(classification[[i]][j], "_FQ"), sep="")[i])*paste("ct$CT1_F", paste0(classification[[i]][j], "_SS"), sep="")*paste("CT1_F", paste0(classification[[i]][j], "_AM"), sep="")
                            } %>%
  lapply(List, function(x) lapply(x, rowSums)) 
  for (i in 1:length(classification))
                paste("ct$CT1_", names(classification[i]), sep="") = rowSums(paste("ct$CT1_F", classification[[i]], sep=""), na.rm = T)             
需求与问题

我希望上述代码实现以下手动代码的效果,但用get()函数始终失败,get()只返回字符类型:

# 所有列均属于名为ct的data.frame。 
 ct$CT1_F095 = ct$CT1_F095_FQ*ct$CT1_F095_SS*ct$CT1_F095_AM,
 ct$CT1_F096 = ct$CT1_F096_FQ*ct$CT1_F096_SS*ct$CT1_F096_AM,
 ct$CT1_F097 = ct$CT1_F097_FQ*ct$CT1_F097_SS*ct$CT1_F097_AM,
 ct$CT1_F098 = ct$CT1_F098_FQ*ct$CT1_F098_SS*ct$CT1_F098_AM,
 ct$CT1_F099 = ct$CT1_F099_FQ*ct$CT1_F099_SS*ct$CT1_F099_AM,
 ct$CT1_F100 = ct$CT1_F100_FQ*ct$CT1_F100_SS*ct$CT1_F100_AM,
 ct$CT1_F101 = ct$CT1_F101_FQ*ct$CT1_F101_SS*ct$CT1_F101_AM,
 ct$CT1_F102 = ct$CT1_F102_FQ*ct$CT1_F102_SS*ct$CT1_F102_AM,
 ct$CT1_F103 = ct$CT1_F103_FQ*ct$CT1_F103_SS*ct$CT1_F103_AM,
 ct$CT1_F104 = ct$CT1_F104_FQ*ct$CT1_F104_SS*ct$CT1_F104_AM,
 ct$CT1_F105 = ct$CT1_F105_FQ*ct$CT1_F105_SS*ct$CT1_F105_AM,
 ct$CT1_F106 = ct$CT1_F106_FQ*ct$CT1_F106_SS*ct$CT1_F106_AM,
 ct$CT1_TOTFR = rowSums(pick(ct$CT1_F095:ct$CT1_F106), na.rm = T),
 ct$CT1_GI_L_F = rowSums(lgi, na.rm = T),
 ct$CT1_GI_M_F = rowSums(mgi, na.rm = T),
 ct$CT1_GI_H_F = rowSums(hgi, na.rm = T),
 ct$CT1_GL_L_F = rowSums(lgl, na.rm = T),
 ct$CT1_GL_M_F = rowSums(mgl, na.rm = T),
 ct$CT1_GL_H_F = rowSums(hgl, na.rm = T)
测试结果

执行代码:

paste("ct$CT1_F", classification[[1]], sep="")

返回结果:

[1] "ct$CT1_F095" "ct$CT1_F096" "ct$CT1_F097" "ct$CT1_F098" "ct$CT1_F099" "ct$CT1_F100"
 [7] "ct$CT1_F101" "ct$CT1_F102" "ct$CT1_F103" "ct$CT1_F104" "ct$CT1_F105" "ct$CT1_F106"

执行:

str(paste("ct$CT1_F", classification[[1]], sep=""))

返回:

chr [1:12] "ct$CT1_F095" "ct$CT1_F096" "ct$CT1_F097" "ct$CT1_F098" "ct$CT1_F099" ...

手动输入:

> ct$CT1_F095

得到数值型结果:

>  [1]  7.00000000  1.75000000  0.75000000  3.50000000  0.75000000  1.75000000  3.50000000
   [8]  0.11627907  0.00000000  0.05813953  0.75000000  5.25000000  0.11627907  0.00000000
  [15]  0.75000000  1.75000000  1.75000000  0.29069767  0.37500000  2.62500000  0.37500000
  [22]  0.29069767  0.87500000  1.74418605  1.75000000  1.50000000  0.75000000  0.14534884
  [29]  1.12500000  2.75000000  0.75000000  1.75000000  3.50000000  0.05813953  4.12500000
  [36]  0.37500000  3.50000000  0.75000000  0.75000000  0.11627907  1.75000000  1.12500000
 [ reached getOption("max.print") -- omitted 64608 entries ]
解决方案

不要用get()操作data.frame的列,直接通过列名字符串索引更可靠。以下是实现需求的代码:

# 提取所有水果编码
fruit_codes <- unlist(classification$totfr)

# 批量计算CT1_Fxxx列
for (code in fruit_codes) {
  col_fq <- paste0("CT1_F", code, "_FQ")
  col_ss <- paste0("CT1_F", code, "_SS")
  col_am <- paste0("CT1_F", code, "_AM")
  col_target <- paste0("CT1_F", code)
  
  ct[[col_target]] <- ct[[col_fq]] * ct[[col_ss]] * ct[[col_am]]
}

# 批量计算各类分组的行和
group_mapping <- list(
  "TOTFR" = classification$totfr,
  "GI_L_F" = classification$lgi,
  "GI_M_F" = classification$mgi,
  "GI_H_F" = classification$hgi,
  "GL_L_F" = classification$lgl,
  "GL_M_F" = classification$mgl,
  "GL_H_F" = classification$hgl
)

for (group_name in names(group_mapping)) {
  col_names <- paste0("CT1_F", unlist(group_mapping[[group_name]]))
  ct[[paste0("CT1_", group_name)]] <- rowSums(ct[col_names], na.rm = TRUE)
}

说明

  1. 用ct[[列名字符串]]的方式直接访问和赋值data.frame的列,避免get()的字符解析问题
  2. 先提取所有水果编码,循环计算每个CT1_Fxxx列
  3. 定义分组映射,循环计算每个分组的行和,代码更简洁易维护

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 02:47:03