这个问题与我的问题有关:My old question
但是,在这个问题中,我想通过函数输出乘以vector元素。
以下是对我的问题的描述:
假设我有一个10
向量列表,并希望按列的特定值乘以每个向量。也就是说,第一个矢量值仅乘以每个数组的第一个元素。然后,第二个矢量值仅乘以每个阵列的第二个元素。对所有载体都这样做。由于我有10
个向量(每个都有100
个值)和100
个数组,因此每个都有10
个非零值。然后,我想如上所述逐个进行乘法。
x[[1]]
将每个元素乘以数组的每个第一个元素。 假设我有一个向量列表,以下向量是我列表的第一个和第二个向量。
[[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]]
列表中工作。
也就是说,我想乘以然后取总和得到单个值。
答案 0 :(得分:0)
正如我在评论中所说,几行代码可以帮助澄清而不是模糊单行。
对于您的问题,您可以利用R进行矢量化计算的事实,即对表格的每个元素进行逐元素计算。
所以我首先要重塑数据。您的示例数据是这样的,如果我错了,请纠正我:
p = n(n-1)/2
个非零值; 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