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

如何用data.table语法替代循环,按country拼接对应survey字符串?

问题描述

我有一个data.table,其中country列存在重复值,survey列的每个观测都是唯一字符串。我希望创建一个新变量,将单个country对应的所有survey字符串按行累积拼接起来。目前我已经通过索引和for循环实现了该功能,但想知道有没有更简便的data.table原生语法实现方式。

我的示例代码如下:

library(data.table)

dt <- data.table(country = c("Belgium","Belgium","Bolivia","Brazil","Brazil","Brazil"),
                      survey = c("BE01, BE03, BE04","BE05, BE07, BE11",
                            "BO11, BO13", "BR01, BR02, BR03", "BR05","BR12, BR13"))
dt[, index := seq(1, .N), by = "country"]
for(cntry in unique(dt$country)){
  tmp_ind <- max(dt[country == eval(cntry)]$index)
  dt[country == eval(cntry) & index ==1, all_surveys := survey]
  if(tmp_ind > 1) {
    for(i in 2:tmp_ind){
      dt[country == eval(cntry) & index ==i,
         all_surveys := paste0(dt[country == eval(cntry) & index == i-1, all_surveys], survey)]
    }
  }
}

运行后得到的预期结果:

> dt
   country           survey index                      all_surveys
1: Belgium BE01, BE03, BE04     1                 BE01, BE03, BE04
2: Belgium BE05, BE07, BE11     2 BE01, BE03, BE04BE05, BE07, BE11
3: Bolivia       BO11, BO13     1                       BO11, BO13
4:  Brazil BR01, BR02, BR03     1                 BR01, BR02, BR03
5:  Brazil             BR05     2             BR01, BR02, BR03BR05
6:  Brazil       BR12, BR13     3   BR01, BR02, BR03BR05BR12, BR13
简化实现方式

在data.table里可以直接利用分组结合累积拼接的方式,不需要额外创建索引和嵌套循环,一行代码就能达成需求:

library(data.table)

dt <- data.table(country = c("Belgium","Belgium","Bolivia","Brazil","Brazil","Brazil"),
                      survey = c("BE01, BE03, BE04","BE05, BE07, BE11",
                            "BO11, BO13", "BR01, BR02, BR03", "BR05","BR12, BR13"))

# 核心逻辑:按country分组,生成累积拼接的字符串
dt[, all_surveys := Reduce(paste0, survey, accumulate = TRUE), by = country]

运行后得到的结果和你用for循环实现的完全一致:

> dt
   country           survey                      all_surveys
1: Belgium BE01, BE03, BE04                 BE01, BE03, BE04
2: Belgium BE05, BE07, BE11 BE01, BE03, BE04BE05, BE07, BE11
3: Bolivia       BO11, BO13                       BO11, BO13
4:  Brazil BR01, BR02, BR03                 BR01, BR02, BR03
5:  Brazil             BR05             BR01, BR02, BR03BR05
6:  Brazil       BR12, BR13   BR01, BR02, BR03BR05BR12, BR13

代码说明

  • Reduce(paste0, survey, accumulate = TRUE):Reduce会依次对当前分组内的survey元素执行paste0拼接,accumulate=TRUE会保留每一步的拼接结果,正好实现按行累积拼接的效果。
  • by = country:确保每个国家的拼接独立进行,不会跨组混合内容。

如果需要在拼接的字符串之间添加分隔符(比如逗号加空格),只需把paste0替换为带sep参数的paste即可:

dt[, all_surveys := Reduce(function(x, y) paste(x, y, sep = ", "), survey, accumulate = TRUE), by = country]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 05:33:18