I have a bunch of data.tables in a list. I want to apply unique() to each data.table in my list, but doing so destroys all my data.table keys.

Here's an example:

A <- data.table(a = rep(c("a","b"), each = 3), b = runif(6), key = "a")
B <- data.table(x = runif(6), b = runif(6), key = "x")

blah <- unique(A)

Here, blah still has a key, and everything is right in the world:

key(blah)

# [1] "a"

But if I add the data.tables to a list and use lapply(), the keys get destroyed:

dt.list <- list(A, B)

unique.list <- lapply(dt.list, unique) # Keys destroyed here

lapply(unique.list, key) 

# [[1]]
# NULL

# [[2]]
# NULL

This probably has to do with me not really understanding what it means for keys to be assigned "by reference," as I've had other problems with keys disappearing.

So:

  • Why does lapply not retain my keys?
  • What does it mean to say keys are assigned "by reference"?
  • Should I even be storing data.tables in a list?
  • How can I safely store/manipulate data.tables without fear of losing my keys?

EDIT:

For what it's worth, the dreaded for loop works just fine, too:

unique.list <- list()

for (i in 1:length(dt.list)) {
  unique.list[[i]] <- unique(dt.list[[i]])
}

lapply(unique.list, key)

# [[1]]
# [1] "a"

# [[2]]
# [1] "x"

But this is R, and for loops are evil.

Edit
Report