Search code examples
rarraysdataframemultiplication

Multiply a list of arrays by a list of dataframes - R


I am trying to multiply a list of arrays by a list of dataframes, but it's not turning out the way I had in mind.

The arrays are a list of 2 with a dimension of 5x2, and the dataframes are a list of 2 with a dimension of 5x2. Below is the data

mat1 <- list(emote = structure(c(32.159, -3.608, -4.763, 
                         5.394, 8.581, 71.258, 0.427, -0.323, 10.427, 21.967), 
                       dim = c(5L, 2L), 
                       dimnames = list(c("(Icpt)", "pl", "ed", "fin", "hp"), c("A", "B"))), 
     sceng = structure(c(105.992, -0.011, 5.847, -10.575, 
                         -24.148, 229.327, 7.864, 18.654, -3.56, -8.6), 
                       dim = c(5L, 2L), 
                       dimnames = list(c("(Icpt)", "pl", "ed", "fin", "hp"), c("A", "B"))))

df1 <- list(emote = structure(list(Var1 = structure(1:5, levels = c("(Icpt)", "pl", "ed", "fin", "hp"), 
                                   class = "factor"), value = c(0.079, 0.013, 0.005, 0.017, 0.013)), 
                               row.names = c(NA, -5L), class = "data.frame"), 
             sceng = structure(list(Var1 = structure(1:5, levels = c("(Icpt)", "pl", "ed", "fin", "hp"), 
                                   class = "factor"), value = c(0.136, 0.027, 0.009, 0.032, 0.021)), 
                               row.names = c(NA, -5L), class = "data.frame"))

What I want to do is multiply the values in columns A and B of array emote by the values in column value of the dataframe emote, and also do the same for columns A and B in array sceng by the values in column value of dataframe sceng.

Under an ideal situation, I think a script like lapply(mat1, '*', df1) should work. I also used mapply(function(x, y) if(all(is.numeric(x), is.numeric(y))) x * y else x, mat1, df1) to exclude character values, but the results were wrong. The final dataframes/arrays I am looking for will be something like below:

$emote
        A       B
(Icpt) 2.5406   5.6294
pl    -0.0469   0.0056
ed    -0.0238  -0.0016
fin    0.0917   0.1773
hp     0.1116   0.2856
        
$sceng
        A       B       
(Icpt) 14.4149  31.1885
pl    -0.0003   0.2123
ed     0.0526   0.1679
fin   -0.3384  -0.1139
hp    -0.5071  -0.1806

Solution

  • You need to multiply it with only value column of df1. Try -

    res <- Map(function(x, y) x * y$value, mat1, df1)
    res
    
    #$emote
    #               A         B
    #(Icpt)  2.540561  5.629382
    #pl     -0.046904  0.005551
    #ed     -0.023815 -0.001615
    #fin     0.091698  0.177259
    #hp      0.111553  0.285571
    
    #$sceng
    #               A         B
    #(Icpt) 14.414912 31.188472
    #pl     -0.000297  0.212328
    #ed      0.052623  0.167886
    #fin    -0.338400 -0.113920
    #hp     -0.507108 -0.180600