简体   繁体   中英

Generically aggregate columns using data.table

I am trying generically aggregate data using data.table package. I have multiple columns that I want to aggregate. I create a initial data table using the following script:

library(data.table)
dt <- data.table(x.1 = rnorm(10, 20, 3), x.2 = rnorm(10, 20, 3), x.3 = rnorm(10, 20, 3),
                 y.1 = rnorm(10, 20, 3), y.2 = rnorm(10, 20, 3), y.3 = rnorm(10, 20, 3),
                 z.1 = rnorm(10, 20, 3), z.2 = rnorm(10, 20, 3), z.3 = rnorm(10, 20, 3))

What I am trying to achieve is to aggregate columns {x1, x2, x3, y1, y2, y3, z1, z2, z3} => {x.total, y.total, z.total} by applying sum to each group of columns.

I can do this using for loops like this:

prefixes <- c('x', 'y', 'z')
initial.colnames <- c(names(dt))

for (i in 1:nrow(dt)){
  for (pref in prefixes){
    dt[,eval(paste0(pref, '.total')) := sum(dt[i, eval(grep(pref, initial.colnames))]), with = TRUE]
  }
}

However, I want to apply using in-line data table construct, something like this:

dt[, eval(paste0(prefixes, '.total')) := sum(dt[,eval(grep(prefixes, initial.colnames))]), with = F]

But this does not give me the required results.

Maybe there are some ideas how would I do that in the right way?

Here's a way to aggregate with melt :

mDT = melt(dt[, r := .I], measure.vars = patterns(prefixes), value.name=prefixes)

mDT[, lapply(.SD, sum), by=r, .SDcols=prefixes]


     r        x        y        z
 1:  1 63.65898 65.41892 56.40470
 2:  2 60.58634 62.71055 48.69771
 3:  3 50.12036 60.06289 66.38637
 4:  4 55.42629 63.38670 56.98914
 5:  5 59.94042 54.28727 49.20218
 6:  6 59.51313 67.53499 59.24097
 7:  7 63.26874 62.23262 60.70875
 8:  8 54.90082 76.09135 58.79787
 9:  9 56.35402 52.11372 60.37903
10: 10 52.77926 55.06044 53.75093

We can use Map with Reduce

dt[,paste0(prefixes, '.total'):= Map(function(i)  Reduce('+',as.list(.SD[,i, with=FALSE])), 
                                split(names(dt), sub('\\..*', '', names(dt))))]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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