2

I'd like to add a vector to a data.table with each name of the vector's elements corresponding to a new column, and the value repeated based on the vector's element value.

So given:

x <- data.table(a=1:2, b=3:4)
v <- c(c=5, d=6)

I'm seeking a result of:

data.table(a=1:2, b=3:4, c=5, d=6)
#    a b c d
# 1: 1 3 5 6
# 2: 2 4 5 6

Things I tried:

cbind adds the vector as a single column:

cbind(x, v)
#    a b v
# 1: 1 3 5
# 2: 2 4 6

Using the approach from Adding multiple columns to a data.table, where column names are held in a vector also vectorizes wrongly (horizontally rather than vertically):

x[, (names(v)) := v]
#    a b c d
# 1: 1 3 5 5
# 2: 2 4 6 6

x[, (names(v)) := list(v)]
# Same as above.
smci
  • 32,567
  • 20
  • 113
  • 146
Max Ghenis
  • 14,783
  • 16
  • 84
  • 132

2 Answers2

5

We can do this without looping too

x[, names(v) := as.list(v)]
x
#   a b c d
#1: 1 3 5 6
#2: 2 4 5 6
akrun
  • 874,273
  • 37
  • 540
  • 662
  • Ah, `as.list` instead of `list`, thanks. Why are parens not needed around `names(v)`? It works with them as well. – Max Ghenis Apr 19 '17 at 16:33
  • 1
    @MaxGhenis It may be better to use parens as it is more general i.e. `cols <- names(v);x[, (cols) := as.list(v)]1 – akrun Apr 19 '17 at 16:37
  • 1
    @Max Really, `v` should be specified using `v = list(c = ...)` from the start. Table rows are (ordered) tuples not vectors. – Frank Apr 19 '17 at 16:43
2

Looping works:

for (i in seq_along(v)) x[, (names(v)[i]) := v[i]]

Result:

x
#    a b c d
# 1: 1 3 5 6
# 2: 2 4 5 6
Max Ghenis
  • 14,783
  • 16
  • 84
  • 132