1

How do I create a data.table column, where the name and column definition are determined by a variable?

In my case, my data.table looks like

dt <- data.table(DeltaPaid = c(1,2,4,8))
dt
   DeltaPaid
1:         1
2:         2
3:         4
4:         8

Now, if a variable cap is passed as 3....

cap <- 3
dt[, DeltaPaid.capped.3:=pmin(3, DeltaPaid)]

dt
   DeltaPaid DeltaPaid.capped.3
1:         1                  1
2:         2                  2
3:         4                  3
4:         8                  3

In other words, I would like the column name to be paste("DeltaPaid.capped.",cap,sep="") and the column definition to be paste(":=pmin(",cap,", DeltaPaid)",sep="").

I tried

dt <- data.table(DeltaPaid = c(1,2,4,8))
cap <- 3
expr <- paste("DeltaPaid.capped.",cap,":=pmin(",cap,", DeltaPaid)",sep="")
dt[, eval(expr)]

with no luck.

I have also seen and read through this question but was unable to get that solution to work for me.

Community
  • 1
  • 1
Ben
  • 20,038
  • 30
  • 112
  • 189
  • 1
    did you look at this: http://stackoverflow.com/questions/11680579/assign-multiple-columns-using-in-data-table-by-group – Mahdi Jadaliha Sep 22 '14 at 22:09
  • I think requiring that someone use `eval` when an ordinary `paste` expression succeeds is overkill. – IRTFM Sep 22 '14 at 22:23

1 Answers1

1
> dt[, paste("cap", names(dt), sep=""):= pmin(3, DeltaPaid)]
> dt
   DeltaPaid capDeltaPaid
1:         1            1
2:         2            2
3:         4            3
4:         8            3

If this were for multiple columsn the same strategy implemented with lapply on the "interior image" (or whatever the real name of .SD might be):

> dt[, paste("cap", names(dt), sep=""):= lapply(.SD, function(x) {pmin(3, x)})]
> dt
   DeltaPaid capDeltaPaid capcapDeltaPaid
1:         1            1               1
2:         2            2               2
3:         4            3               3
4:         8            3               3
> dt[, paste("cap", names(dt), sep=""):= lapply(.SD, function(x) {pmin(3, x)})]
> dt
   DeltaPaid capDeltaPaid capcapDeltaPaid capcapcapDeltaPaid
1:         1            1               1                  1
2:         2            2               2                  2
3:         4            3               3                  3
4:         8            3               3                  3
IRTFM
  • 258,963
  • 21
  • 364
  • 487