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

R语言for循环中动态生成mutate变量失败,求正确实现方案

动态生成R数据框变量的循环修正方案

问题背景

需要基于给定年龄值(20、30、40、50)动态生成对应的日期变量和暴露年数变量,手动编写mutate语句可得到正确结果,但循环代码仅输出最后一次迭代结果且目标列全为NA。

模拟数据框dfhave

structure(list(ID = 1:10, DOB = structure(c(-3704, -7119, -7375, 
-8217, -8504, -4886, -6899, -3027, -5546, -4512), class = "Date"), 
    date1 = structure(c(7284, 9182, 4609, 6370, 5796, 9004, 8215, 
    5391, 8778, 6724), class = "Date"), date2 = structure(c(12429, 
    10203, 10764, 14487, 11367, 14495, 14845, 12190, 10216, 13144
    ), class = "Date"), age.date1 = c(30.0835044490075, 44.6297056810404, 
    32.8104038329911, 39.937029431896, 39.1512662559891, 38.0287474332649, 
    41.3798767967146, 23.047227926078, 39.2169746748802, 30.7624914442163
    ), age.date2 = c(44.1697467488022, 47.4250513347023, 49.6618754277892, 
    62.1601642710472, 54.403832991102, 53.0622861054073, 59.5318275154004, 
    41.6618754277892, 43.1540041067762, 48.3394934976044)), row.names = c(NA, 
10L), class = "data.frame")

手动实现的正确代码(生成dfwant)

dfwant <- dfhave %>% mutate(age20day = DOB %m+% years(20),
                        age30day = DOB %m+% years(30),
                        age40day = DOB %m+% years(40),
                        age50day = DOB %m+% years(50),
                    
                    expyrs.20 = case_when(age.date1<=20 & age.date2<=20 ~ as.duration(date1 %--% date2)/dyears(1),
                                          age.date1<=20 & age.date2>20 ~ as.duration(date1 %--% age20day)/dyears(1), 
                                          age.date1>20 ~ 0),
                    
                    expyrs.30 = case_when(age.date1<=30 & age.date2<=30 ~ as.duration(date1 %--% date2)/dyears(1),
                                          age.date1<=30 & age.date2>30 ~ as.duration(date1 %--% age30day)/dyears(1), 
                                          age.date1>30 ~ 0),
                    
                    expyrs.40 = case_when(age.date1<=40 & age.date2<=40 ~ as.duration(date1 %--% date2)/dyears(1),
                                          age.date1<=40 & age.date2>40 ~ as.duration(date1 %--% age40day)/dyears(1), 
                                          age.date1>40 ~ 0),
                    
                    expyrs.50 = case_when(age.date1<=50 & age.date2<=50 ~ as.duration(date1 %--% date2)/dyears(1),
                                            age.date1<=50 & age.date2>50 ~ as.duration(date1 %--% age50day)/dyears(1), 
                                            age.date1>50 ~ 0)
                    
                    )

错误的循环代码

ages <- c(20,30,40,50)

for (i in ages) {
  
ageday =  paste0("age", i, "day")
expyrs =  paste0("expyrs.", i)
  
 df2 <- dfhave %>% mutate(!!ageday := DOB %m+% years(i),
    
    !!expyrs := case_when(age.date1<=ages[i] & age.date2<=ages[i] ~ as.duration(date1 %--% date2)/dyears(1),
                                                             age.date1<=ages[i] & age.date2>ages[i] ~ as.duration(date1 %--% as.Date(!!sym(ageday)))/dyears(1), 
                                                             age.date1>ages[i] ~ 0
  )
  )
}

错误表现

运行后仅保留最后一次迭代的age50day和expyrs.50,且expyrs.50列全为NA。

错误原因分析

  1. 数据框覆盖问题:每次循环都从原始dfhave重新生成df2,未基于上一次循环的结果累加变量,导致之前生成的变量被丢弃。
  2. 索引逻辑错误:ages[i]用法有误,i是ages中的元素值(如20、30)而非索引位置,ages[i]实际取的是ages[20]这类不存在的位置,返回NA,导致case_when条件全不满足,结果为NA。
  3. 变量引用冗余:case_when中无需用as.Date(!!sym(ageday)),直接使用刚生成的!!sym(ageday)即可,多余的类型转换可能引发问题。

修正后的循环代码

library(lubridate)
library(dplyr)

ages <- c(20, 30, 40, 50)
# 初始化df2为原始数据框,确保变量逐步累加
df2 <- dfhave

for (i in ages) {
  ageday <- paste0("age", i, "day")
  expyrs <- paste0("expyrs.", i)
  
  df2 <- df2 %>%
    mutate(
      !!ageday := DOB %m+% years(i),
      !!expyrs := case_when(
        age.date1 <= i & age.date2 <= i ~ as.duration(date1 %--% date2)/dyears(1),
        age.date1 <= i & age.date2 > i ~ as.duration(date1 %--% !!sym(ageday))/dyears(1),
        age.date1 > i ~ 0
      )
    )
}

验证结果

修正后的代码会逐步累加生成age20day到age50day以及expyrs.20到expyrs.50变量,与手动编写的dfwant结果完全一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 20:29:50