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

如何在data.table的by参数中向函数传递字符向量?

解决data.table中by参数传递字符向量给函数的问题,以及按月份聚合日期的需求

我来帮你搞定这两个问题,先从核心的by参数传递字符向量的问题说起,再讲日期聚合的规范做法。

为什么你的代码无效?

你之前试的这两行代码:

df[, .(n = .N), by = str_sub(chosen_col, 1, 7)]
df[, .(n = .N), by = eval(str_sub(chosen_col, 1, 7))]

问题出在:str_sub(chosen_col, 1,7)是对字符串"dates"本身截取(结果是"dates"前7个字符,也就是"dates"),而不是对df$dates列里的日期值操作。eval在这里也没起到作用,因为它没有引用到data.table内部的列数据。

正确的解决方法(核心问题:传递字符向量给by参数的函数)

方法1:用get()获取列并处理

get()函数可以从data.table的环境中取出指定名称的列,然后直接对列值应用函数:

library(data.table)
library(stringr)

df <- data.table(dates = c('2017-01-01', '2017-01-05'))
chosen_col <- 'dates'

# 正确写法:用get()拿到列的值,再用str_sub处理
df[, .(n = .N), by = str_sub(get(chosen_col), 1, 7)]

运行后会得到按2017-01分组的计数结果。

方法2:用.SDcols和.SD操作列

.SDcols指定要操作的列,.SD代表这些列组成的子数据集,用.SD[[1]]取出对应列的值:

df[, .(n = .N), by = .(month = str_sub(.SD[[1]], 1, 7)), .SDcols = chosen_col]

这种方式适合同时处理多列的场景,这里单列也适用,还能给分组键起个清晰的名字month。

按月份聚合日期的规范做法

既然你提到了日期聚合的变通方法,这里再补充几个更规范的日期处理方式(推荐先把字符串转成Date类型):

# 先把dates列转成Date类型
df[, dates := as.Date(dates)]

# 方法1:用lubridate的yearmonth函数直接生成年月分组
library(lubridate)
df[, .(n = .N), by = yearmonth(dates)]

# 方法2:拆分成年和月分组,或者合并成年月字符串
df[, .(n = .N), by = .(year = year(dates), month = month(dates))]
# 合并成年月格式字符串
df[, .(n = .N), by = sprintf("%04d-%02d", year(dates), month(dates))]

这些方法比直接截取字符串更可靠,能避免日期格式不规范带来的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 21:57:47