Reputation: 1225
I have a list of 20-length vectors that I would like to multiply each of those with one of three matrices depending on the length vectors' names. Here is my unsuccessful attempt. Please suggest how I improve my code. Any help is much appreciated!
for (i in 1:length(List)){
.$Value=ifelse(names(List) %in% c("a","b","c"),matrixA%*%.$Value,ifelse(names(List) %in% c("d","e"),matrixB%*%.$Value, matrixC%*%.$Value))
}
Part of my list and the matrices are included below.
list(a = structure(c(3, 0, 0, 5, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 10, 0, 0, 1, 1), .Dim = c(20L, 1L)), b = structure(c(2,
0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 6, 0), .Dim = c(20L,
1L)))
matrixA <- diag(2,20)
matrixB <- diag(1,20)
matrixC <- diag(4,20)
Upvotes: 1
Views: 55
Reputation: 48
So... Not sure I understand. But it seems like if the list has name a, b or c you want to multiply it to matrixA, if it's d or e you want to multiply it to matrixB and if neither, the values should be multiplied to matrixC.
Let's use your example.
zz <- list(a = structure(c(3, 0, 0, 5, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 10, 0, 0, 1, 1), .Dim = c(20L, 1L)), b = structure(c(2,
0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 6, 0), .Dim = c(20L,
1L)))
matrixA <- diag(2,20)
matrixB <- diag(1,20)
matrixC <- diag(4,20)
This is probably not the best solution but it is a simple one. I just made a few tweaks to your ideia so it would work, a matrix needs to be protected by list() (because a list is a vector, and ifelse works with vectors) inside an ifelse() otherwise you only get the first element. This will return you a list of the results.
results <- lapply(seq_along(zz), function(i){
ifelse(names(zz[i]) %in% c("a","b","c"),list(matrixA%*%zz[[i]]),
ifelse(names(zz[i]) %in% c("d","e"), list(matrixB%*%zz[[i]]), list(matrixC%*%zz[[i]])))
})
I used lapply to apply the sequence to (1 to length of zz) to the defined function. For each i the function looks at the name of i element zz (zz[i] returns the element of the list with its name) and if it satisfies the condition we multiply the content of the i element of zz (zz[[i]] just returns the content of the i element of the list without its name) by a predefined matrix.
This also works and you don't need to protect the matrix using list() which is kinda of a bother.
results <- lapply(seq_along(zz), function(i){
if(names(zz[i]) %in% c("a","b","c")) matrixA%*%zz[[i]] else
if(names(zz[i]) %in% c("d","e")) matrixB%*%zz[[i]]
else matrixC%*%zz[[i]]
})
Edit: @akrun answer is way more beautiful and short.
Upvotes: 1
Reputation: 887048
May be this helps
nm1 <- paste0("matrix", toupper(names(lst1)))
Map(crossprod, lst1, mget(nm1))
Upvotes: 1