将两个不规则长度的列表相乘

时间:2018-12-21 14:03:42

标签: r list mapply do.call

我有类似的列表

a <- list(list(c(-2,1), 4:5, 2:3), list(c(0,2), c(-1,1)))
b <- list(7:9, c(5,-1))

> a
[[1]]
[[1]][[1]]
[1] -2  1

[[1]][[2]]
[1] 4 5

[[1]][[3]]
[1] 2 3


[[2]]
[[2]][[1]]
[1] 0 2

[[2]][[2]]
[1] -1  1



> b
[[1]]
[1] 7 8 9

[[2]]
[1]  5 -1

我想将a[[1]中的(-2,1)中的每一个与b[[1]]中的7相乘,以获得(-14,7),(4,5)中的每一个与8,每个(2,3)与9,然后(0,2)每个与5,最后(-1,1)每个与-1。

对于i = 1,2,我可以确定length(a[[i]])==length(b[[i]])TRUE(实际上,i更大),因此对于所需的乘法,有正确数量的条目。

但是,不清楚a[[i]])有多少个条目(在示例中,a[[1]]为3个,a[[2]]为2个,或者等效地,{{1}多长时间}),但它们将至少具有一个条目。因此,将b[[i]]a转换成矩阵似乎不切实际。

我不确定这是否与问题有关,但是也可能是我们在每个b(即2个)中有与a[[i]])个一样多的条目

我在想a[[i]])do.call的某种组合,但无法使其正常工作。

2 个答案:

答案 0 :(得分:4)

我们确实可以使用mapply(和Map,与mapply相同,但使用SIMPLIFY = FALSE)。根据格式(@RonakShah的答案中的矩阵或问题中的列表),可以使用

Map(mapply, a, b, MoreArgs = list(FUN = `*`))
# [[1]]
#      [,1] [,2] [,3]
# [1,]  -14   32   18
# [2,]    7   40   27
#
# [[2]]
#      [,1] [,2]
# [1,]    0    1
# [2,]   10   -1

Map(Map, a, b, MoreArgs = list(f = `*`))
# [[1]]
# [[1]][[1]]
# [1] -14   7
#
# [[1]][[2]]
# [1] 32 40
#
# [[1]][[3]]
# [1] 18 27
#
#
#[[2]]
# [[2]][[1]]
# [1]  0 10
#
# [[2]][[2]]
# [1]  1 -1

替代tidyverse的是

map2(a, b, map2, `*`)

答案 1 :(得分:1)

因此,您可以确保length(a[[i]])==length(b[[i]])可以在mapply内使用lapply

lapply(seq_along(a), function(x) mapply("*", a[[x]], b[[x]]))


#[[1]]
#     [,1] [,2] [,3]
#[1,]  -14   32   18
#[2,]    7   40   27

#[[2]]
#     [,1] [,2]
#[1,]    0    1
#[2,]   10   -1