Умножить список векторов на разные матрицы, обусловленные именами векторов - PullRequest
1 голос
/ 08 июня 2019

У меня есть список из 20 векторов длины, которые я хотел бы умножить на каждый из них с одной из трех матриц в зависимости от имен векторов длины.Вот моя неудачная попытка.Пожалуйста, предложите, как я могу улучшить свой код.Любая помощь очень ценится!

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))
}

Часть моего списка и матрицы включены ниже.

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)

Ответы [ 2 ]

1 голос
/ 08 июня 2019

Может быть, это помогает

nm1 <- paste0("matrix", toupper(names(lst1)))
Map(crossprod, lst1, mget(nm1))
0 голосов
/ 08 июня 2019

Итак ... Не уверен, что понимаю. Но похоже, что если список имеет имя a, b или c , вы хотите умножить его на matrixA , если это d или e , вы хотите умножить его до matrixB и, если нет, значения следует умножить на matrixC .

Давайте использовать ваш пример.

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)

Возможно, это не лучшее решение, но оно простое. Я только что сделал несколько настроек для вашей идеи, чтобы она работала, матрица должна быть защищена с помощью list () (потому что список - это вектор, а ifelse работает с векторами) внутри ifelse () в противном случае вы получите только первый элемент. Это вернет вам список результатов.

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]])))
})

Я использовал lapply, чтобы применить последовательность к (от 1 до длины zz) к определенной функции. Для каждого i функция просматривает имя i element zz (zz [i] возвращает элемент списка с его именем) и, если оно удовлетворяет при условии, что мы умножаем содержимое элемента i на zz (zz [[i]] просто возвращает содержимое элемента i списка без его имя) по заранее определенной матрице.

Это также работает, и вам не нужно защищать матрицу с помощью list (), что немного мешает.

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]]

})

Редактировать: @akrun ответ гораздо красивее и короче.

...