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

使用rlang与purrr基于现有列子集创建新列

批量生成年份占比列的解决方案

针对你需要批量处理多年份列、避免手动逐个生成pct_good列的需求,可以结合purrr和rlang实现动态变量引用与列生成,具体步骤如下:

完整代码实现

library(dplyr)
library(purrr)
library(rlang)
library(stringr) # 用于提取年份,也可替换为基础R方法

# 原始数据框
df <- tibble(good_2018 = 0,
             bad_2018 = 1,
             id_2018 = 0,
             good_2019 = 3,
             bad_2019 = 1,
             id_2019 = 1)

# 提取所有唯一年份(从列名中匹配4位数字)
years <- colnames(df) %>% 
  str_extract("\\d{4}") %>% 
  unique() %>% 
  na.omit()

# 批量生成pct_good列并合并到原数据框
df_with_pct <- df %>% 
  bind_cols(
    map_dfc(years, function(year) {
      # 动态创建各年份对应的变量符号
      good_col <- sym(paste0("good_", year))
      bad_col <- sym(paste0("bad_", year))
      id_col <- sym(paste0("id_", year))
      
      # 计算占比并生成新列,动态命名列名
      transmute(
        .,
        !!paste0("pct_good_", year) := if_else(!!id_col == 0, 0,
                                              100 * !!good_col / (!!good_col + !!bad_col))
      )
    })
  )

# 查看最终结果
print(df_with_pct)

关键步骤解释

  1. 提取年份:
    从数据框的列名中提取出所有4位数字的年份,去重后得到需要处理的年份列表。如果不想依赖stringr,可以用基础R的正则替换实现:

    years <- sub(".*_(\\d{4})", "\\1", colnames(df)) %>% unique() %>% na.omit()
    
  2. 动态变量与列生成:

    • 用sym()将拼接好的列名(如good_2018)转换为符号对象,让dplyr能够识别这些动态生成的列名。
    • 用!!(解引用运算符)将符号对象转换为实际的列引用,在if_else和计算式中调用对应年份的列。
    • 用:=实现动态列命名,将pct_good_年份作为新列的名称。
    • map_dfc会将每个年份生成的单列数据框按列合并,最终和原数据框通过bind_cols组合。

输出结果

运行代码后得到的结果与手动生成的完全一致:

#> # A tibble: 1 × 8
#>   good_2018 bad_2018 id_2018 good_2019 bad_2019 id_2019 pct_good_2018 pct_good_2019
#>       <dbl>    <dbl>   <dbl>     <dbl>    <dbl>   <dbl>         <dbl>          <dbl>
#> 1         0        1       0         3        1       1             0             75

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 19:20:47