Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to merge all elements of a list with another data table on condition

I have the following data:

library(data.table)

dt1 <- data.table(var1 = c("wk1","wk1","wk2"),
                  var2 = c(1,2,3))

dt2 <- data.table(var3 = c("a","b","c"),
                  var2 = c(1,2,3))

lista <- list(dt1,dt2)

dt_main <- data.table(var1 = c("wk1","wk2"),
                      var4 = c(100,200))

I want to merge all elements of lista which contain the variable var1 with the dt_main data.table, so in the end I would like lista to look like this:

dt1 <- data.table(var1 = c("wk1","wk1","wk2"),
                  var2 = c(1,2,3),
                  var4 = c(100,100,200))

dt2 <- data.table(var3 = c("a","b","c"),
                  var2 = c(1,2,3))

lista <- list(dt1,dt2)

I tried

mapply(function(X,Y){
  if("var1"%in%names(X)){
    X <- merge(X,Y,by="var1")
  }
},X=lista,Y=dt_main)

but it does not work. Any help ?

like image 632
quant Avatar asked Nov 29 '17 09:11

quant


2 Answers

You could use an lapply and merge inside the function:

lapply(lista, function(x) if (!is.null(x$var1)) {

  #the function checks if there is a var1 column
  #and if there is, it gets merged to the x data.table
  return(merge(dt_main, x, by = 'var1', all.x = TRUE))

} else {

  #otherwise it just returns the data.table
  return(x)

})

# [[1]]
#    var1 var4 var2
# 1:  wk1  100    1
# 2:  wk1  100    2
# 3:  wk2  200    3
# 
# [[2]]
#    var3 var2
# 1:    a    1
# 2:    b    2
# 3:    c    3
like image 134
LyzandeR Avatar answered Oct 20 '22 16:10

LyzandeR


A somewhat different way of doing this:

lapply(lista, function(x) if ('var1' %in% names(x))
  x[dt_main, on = 'var1', var4 := var4][]
  else x
  )

which gives:

[[1]]
   var1 var2 var4
1:  wk1    1  100
2:  wk1    2  100
3:  wk2    3  200

[[2]]
   var3 var2
1:    a    1
2:    b    2
3:    c    3
like image 4
Jaap Avatar answered Oct 20 '22 16:10

Jaap