Select which columns in list matrices to perform mathematical operations on as defined by another list

Viewed 25

Suppose I have a list containing two matrices with different dimensions.

a <- matrix(rnorm(n=12), nrow = 3, ncol=4)
b <- matrix(rnorm(n=12), nrow = 4, ncol=3)
list1 <- list(a, b)

list1

#[[1]]
#           [,1]       [,2]      [,3]      [,4]
#[1,] -1.4654114  2.1251278 2.5363265 0.3127435
#[2,]  0.5701815 -1.0877491 0.6314599 1.5293045
#[3,]  2.0811299  0.3109243 0.2300760 0.5495488
#
#[[2]]
#          [,1]      [,2]     [,3]
#[1,] 0.9082071 1.7337076 2.207299
#[2,] 2.1287871 1.6839454 1.527546
#[3,] 0.8175804 0.8086223 1.165589
#[4,] 0.7410989 0.8237012 1.729501

Additionally, I have a list containing two vectors.

a2 <- c("yes", "no", "yes", "yes")
b2 <- c("no", "yes", "no")
list2 <- list(a2, b2)

list2

#[[1]]
#[1] "yes" "no"  "yes" "yes"
#
#[[2]]
#[1] "no"  "yes" "no" 

How can I perform mathematical operations only on the columns in list1 that correspond to where list2 says "yes" and keep those updated columns in the original list matrices? For example how could I multiply the values in those "yes" columns by 10 and leave the "no" columns unaltered? Thank you in advance!

1 Answers

Here is a base R option using Map

Map(function(x, y) { x[, y == "yes"] <- 10 * x[, y == "yes"]; x }, list1, list2)
#[[1]]
#           [,1]       [,2]      [,3]      [,4]
#[1,]   3.769721 -1.1304059  9.391210  1.173668
#[2,]   3.015484 -2.7965343 -2.293777 -8.531228
#[3,] -10.980232  0.7205735 17.591313  9.092592
#
#[[2]]
#.          [,1]        [,2]        [,3]
#[1,]  1.1963730  17.0399588  2.17436525
#[2,] -0.3715839 -30.3876461  1.09818265
#[3,] -0.1232602 -22.8897495  0.31822032
#[4,]  1.8000431   0.5830349 -0.07314756

PS. Please note that my sample data is different from yours as you didn't specify a fixed random seed (see my sample data below).

More generally you can define a function

f <- function(x) 10 * x
Map(function(x, y) { x[, y == "yes"] <- f(x[, y == "yes"]); x }, list1, list2)

Sample data

set.seed(2020)
a <- matrix(rnorm(n=12), nrow = 3, ncol=4)
b <- matrix(rnorm(n=12), nrow = 4, ncol=3)
list1 <- list(a, b)
a2 <- c("yes", "no", "yes", "yes")
b2 <- c("no", "yes", "no")
list2 <- list(a2, b2)

list1
#[[1]]
#.          [,1]       [,2]       [,3]       [,4]
#[1,]  0.3769721 -1.1304059  0.9391210  0.1173668
#[2,]  0.3015484 -2.7965343 -0.2293777 -0.8531228
#[3,] -1.0980232  0.7205735  1.7591313  0.9092592
#
#[[2]]
#.          [,1]        [,2]        [,3]
#[1,]  1.1963730  1.70399588  2.17436525
#[2,] -0.3715839 -3.03876461  1.09818265
#[3,] -0.1232602 -2.28897495  0.31822032
#[4,]  1.8000431  0.05830349 -0.07314756
Related