如何在R

时间:2018-03-28 08:08:08

标签: arrays r

这个问题与我的问题有关:My old question

但是,在这个问题中,我想通过函数输出乘以vector元素。

以下是对我的问题的描述:

想法

假设我有一个10向量列表,并希望按列的特定值乘以每个向量。也就是说,第一个矢量值仅乘以每个数组的第一个元素。然后,第二个矢量值仅乘以每个阵列的第二个元素。对所有载体都这样做。由于我有10个向量(每个都有100个值)和100个数组,因此每个都有10个非零值。然后,我想如上所述逐个进行乘法。

实施例

  1. 获取列表的第一个向量。然后x[[1]]将每个元素乘以数组的每个第一个元素。
  2. 然后第二个向量值乘以数组的每个第二个元素。
  3. 然后,第三个向量值乘以数组的每个第三个元素。
  4. 为所有其他载体执行此操作。
  5. 数值示例

    假设我有一个向量列表,以下向量是我列表的第一个和第二个向量。

    [[1]]
     [1] 2.174090 1.666464 1.915763 2.282967 2.407327 1.386437 2.854528 1.896338 2.010713 1.013387 .......... (`100` values)
    
    [[2]]
     [1]  2.3020147  3.3311029 -0.3103701  3.2445878  5.6261224  5.2914477 -1.0621042  3.0790536  3.6186598
    [10]  4.1846937 ........ (`100` values)
    
    [[3]]
     [1]  0.42808525  4.02348551 -2.31160703  5.56077594  2.83856320 -0.02850242  1.57480238 -2.68603276
     [9]  2.34598854  4.14115289 ....(`100` values)
    

    假设我有一个包含100值的数组(10)数组列表。让我们以下数组是我的数组列表的第一个和第二个数组。

    , , 1
    
               [,1]        [,2]       [,3]      [,4] [,5]
    [1,]  0.0000000  0.00000000  0.0000000  0.000000    0
    [2,] -0.4610817  0.00000000  0.0000000  0.000000    0
    [3,]  0.4697426 -0.07296078  0.0000000  0.000000    0
    [4,] -0.2790043 -0.77459992 -0.7478920  0.000000    0
    [5,] -0.2156273 -2.59804286 -0.9390597 -1.746925    0
    
        , , 2
    
                [,1]       [,2]       [,3]      [,4] [,5]
    [1,]  0.00000000  0.0000000  0.0000000  0.000000    0
    [2,] -0.21896586  0.0000000  0.0000000  0.000000    0
    [3,] -0.09066381  0.2920374  0.0000000  0.000000    0
    [4,]  1.27289131 -0.2748794  1.0862465  0.000000    0
    [5,] -1.20050567 -1.0934879 -0.7707806 -2.180104    0
    

    然后我想将第一个向量的第一个元素乘以数组的第一个非零值。也就是2.174090 * -0.4610817然后,第一个矢量的第二个元素将乘以第二个数组的第一个元素,即1.666464 * -0.21896586。然后,第二个向量的第一个元素乘以第一个数组的第二个元素,即2.3020147 * 0.4697426 ,第二个向量的第二个元素乘以第二个元素的第二个元素第二个数组3.3311029 * -0.09066381

    第三个向量乘以数组的每个第三个元素。

    0.42808525 * -0.2790043

    那是:

    第一个向量的元素仅乘以数组的第一个元素(逐个)。然后,第二个向量仅乘以数组的第二个元素

    代码:

    set.seed(24)
    myfun <- function(n, N){
      a <- array(rnorm(n * n * N), c(n, n, N))
      for(k in seq(dim(a)[3])) a[,,k][upper.tri(a[,,k], diag = TRUE)] <- 0
      out <- list()
      out$a <- a
      return(out)
    }
    

    我希望代码几乎只有一行。因为我有一个复杂的函数,其输出在形状上类似于我的函数输出。

    res <- sum(x* myfun(5,10)$a)
    

    我试过了:

    x <- rnorm(10,2,2)
    
    x <- rep(list(x), 10)
    
    res <- myfun(5,10)$a
    res[res != 0] <- res[res != 0]*x[[1]]
    

    但是,它没有按预期工作,我也想使代码不仅仅在x[[1]]列表中工作。

    也就是说,我想乘以然后取总和得到单个值。

1 个答案:

答案 0 :(得分:0)

正如我在评论中所说,几行代码可以帮助澄清而不是模糊单行。

对于您的问题,您可以利用R进行矢量化计算的事实,即对表格的每个元素进行逐元素计算。

所以我首先要重塑数据。您的示例数据是这样的,如果我错了,请纠正我:

  • 维度(n,n,N)的数组,您将其描述为具有n×n值的N个数组的“列表”,其中上三角形为零:它们包含p = n(n-1)/2个非零值;
  • 长度为N
  • p个向量的列表

输入数据:

N <- 10
n <- 3
p <- n*(n-1)/2  # = 3

veclist <- list(
  c(2.174090, 1.666464, 1.915763, 2.282967, 2.407327, 1.386437, 2.854528, 1.896338, 2.010713, 1.013387),
  c(2.3020147, 3.3311029, -0.3103701, 3.2445878, 5.6261224, 5.2914477, -1.0621042, 3.0790536, 3.6186598, 4.1846937),
  c(0.42808525, 4.02348551, -2.31160703, 5.56077594, 2.83856320, -0.02850242, 1.57480238, -2.68603276, 2.34598854, 4.14115289)
)

arr <- myfun(n, N)$a

重塑:

mat <- matrix(unlist(veclist), nrow=length(veclist), byrow=T)
dim(mat) # 3 10

# reformat the lower triangle data of arrays
flatarr <- sapply(1:N, function(i) arr[,,i][lower.tri(arr[,,i])])
dim(flatarr) # 3 10

进行逐元素乘法:

res <- mat * flatarr

所以真的只是重塑的问题。

解释

上面的sapply行将相同的函数应用于10个数组中的每一个。这个功能是:

function(i) {
    # take the array number `i`
    ai <- arr[,,i]
    # get the lower triangle values
    ai[lower.tri(ai)]
}

sapply的输出自动简化为维度矩阵(3,10),即3行和10列。

展平数组时的注意事项:

R按列获取矩阵元素。如果你想要的顺序是行,你必须转置数组并取upper.tri,所以sapply函数如下:

function(i) t(arr[,,i])[upper.tri(t(arr[,,i]))]

一衬垫

(定义{{​​1}}和veclist后)

arr <- myfun(n,N)$a