我试图在data.table中的动态选择列上执行最小/最大聚合.它适用于数字列但我不能让它在Date列上工作,除非我创建一个临时data.table.
它在我使用名称时有效:
dt <- data.table(Index=1:31, Date = seq(as.Date('2015-01-01'), as.Date('2015-01-31'), by='days'))
dt[, .(minValue = min(Date), maxValue = max(Date))]
# minValue maxValue
# 1: 2015-01-01 2015-01-31
当我使用= FALSE时,它不起作用:
colName = 'Date'
dt[, .(minValue = min(colName), maxValue = max(colName)), with=F]
# Error in `[.data.table`(dt, , .(minValue = min(colName), maxValue = max(colName)), :
# could not find function "."
我可以在数字列上使用.SDcols:
colName = 'Index'
dt[, .(minValue = min(.SD), maxValue = max(.SD)), .SDcols=colName]
# minValue maxValue
# 1: 1 31
但是当我对Date列执行相同操作时出现错误:
colName = 'Date'
dt[, .(minValue = min(.SD), maxValue = max(.SD)), .SDcols=colName]
# Error in FUN(X[[i]], ...) :
# only defined on a data frame with all numeric variables
如果我使用lapply(.SD,min)或sapply(),则日期将更改为数字.
以下工作,似乎并没有浪费内存,而且速度很快.有更好的吗?
a <- dt[, colName, with=F]
setnames(a, 'a')
a[, .(minValue = min(a), maxValue = max(a))]
最佳答案 在你的第一次尝试:
dt[, .(minValue = min(colName), maxValue = max(colName)), with=F]
# Error in `[.data.table`(dt, , .(minValue = min(colName), maxValue = max(colName)), :
# could not find function "."
您应该阅读Introduction to data.table小插图以了解= =的含义.如果你知道来自基地R的with()函数会更容易.
在第二个:
dt[, .(minValue = min(.SD), maxValue = max(.SD)), .SDcols=colName]
# Error in FUN(X[[i]], ...) :
# only defined on a data frame with all numeric variables
对于带有属性的列的data.frame / data.table,这似乎是min()和max()的问题.这是一个MRE.
df = data.frame(x=as.Date("2015-01-01"))
min(df)
# Error in FUN(X[[i]], ...) :
# only defined on a data frame with all numeric variables
要回答您的问题,您可以使用get():
dt[, .(min = min(get(colName)), max = max(get(colName)))]
或者@Frank建议,[[运算符对列进行子集化:
dt[, .(min = min(.SD[[colName]]), max = max(.SD[[colName]]))]
还没有一种更好的方法将.SD应用于多个函数(因为基本R似乎没有一个AFAICT,而data.table尝试尽可能多地使用基本R函数).有一个FR #1063来解决这个问题.如果/何时实现,那么可以做,例如:
# NOTE: not yet implemented, FR #1063
dt[, colwise(.SD, min, max), .SDcols = colName]