繁体   English   中英

R data.table - 将函数A应用于某些列,将函数B应用于其他列

[英]R data.table - Apply function A to some columns and function B to some others

我想聚合数据表的行,但是aggragation函数取决于列的名称。

例如,如果列名是:

  • variable1variable2 ,然后应用mean()函数。
  • variable3 ,然后应用max()函数。
  • variable4 ,然后应用sd()函数。

我的数据表总是有一个datetime列:我想按时间聚合行。 但是,“数据”列的数量可以变化。

我知道如何使用相同的聚合函数(例如mean() )为所有列做到这一点:

dt <- dt[, lapply(.SD, mean),
           by = .(datetime = floor_date(datetime, timeStep))]

或者仅针对列的子集:

cols <- c("variable1", "variable2")    
dt <- dt[ ,(cols) := lapply(.SD, mean), 
            by = .(datetime = floor_date(datetime, timeStep)),
            .SDcols = cols]

我想做的是:

colsToMean <- c("variable1", "variable2") 
colsToMax <- c("variable3")   
colsToSd <- c("variable4")   
dt <- dt[ ,{(colsToMean) := lapply(.SD???, mean),
             (colsToMax) := lapply(.SD???, max),
             (colsToSd) :=  lapply(.SD???, sd)}, 
            by = .(datetime = floor_date(datetime, timeStep)),
            .SDcols = (colsToMean, colsToMax, colsToSd)]

我查看了R中的data.table - 将多个函数应用到多个列 ,这让我有了使用自定义函数的想法:

myAggregate <- function(x, columnName) {
   FUN = getAggregateFunction(columnName) # Return mean() or max() or sd()
   return FUN(x)
}
dt <- dt[, lapply(.SD, myAggregate, ???columName???),
           by = .(datetime = floor_date(datetime, timeStep))]

但我不知道如何将当前列名传递给myAggregate() ...

以下是使用Mapmapply执行此操作的一种方法:

让我们先制作一些玩具数据:

dt <- data.table(
    variable1 = rnorm(100),
    variable2 = rnorm(100),
    variable3 = rnorm(100),
    variable4 = rnorm(100),
    grp = sample(letters[1:5], 100, replace = T)
)

colsToMean <- c("variable1", "variable2") 
colsToMax <- c("variable3")   
colsToSd <- c("variable4")

然后,

scols <- list(colsToMean, colsToMax, colsToSd)
funs <- rep(c(mean, max, sd), lengths(scols))

# summary
dt[, Map(function(f, x) f(x), funs, .SD), by = grp, .SDcols = unlist(scols)]

# or replace the original values with summary statistics as in OP
dt[, unlist(scols) := Map(function(f, x) f(x), funs, .SD), by = grp, .SDcols = unlist(scols)]

GForce的另一个选择:

scols <- list(colsToMean, colsToMax, colsToSd)
funs <- rep(c('mean', 'max', 'sd'), lengths(scols))

jexp <- paste0('list(', paste0(funs, '(', unlist(scols), ')', collapse = ', '), ')')
dt[, eval(parse(text = jexp)), by = grp, verbose = TRUE]

# Detected that j uses these columns: variable1,variable2,variable3,variable4 
# Finding groups using forderv ... 0.000sec 
# Finding group sizes from the positions (can be avoided to save RAM) ... 0.000sec 
# Getting back original order ... 0.000sec 
# lapply optimization is on, j unchanged as 'list(mean(variable1), mean(variable2), max(variable3), sd(variable4))'
# GForce optimized j to 'list(gmean(variable1), gmean(variable2), gmax(variable3), gsd(variable4))'
# Making each group and running j (GForce TRUE) ... 0.000sec 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM