I have two lists A_1
and A_2
, each contains two matrices.
A_1 <- list(a=matrix(1:8, 2), b=matrix(2:9, 2))
A_2 <- list(a=matrix(10:17, 2), b=matrix(5:12, 2))
I'd like to calculate element-wise averages of these two lists which results a list of
lst((A_1$a A_2$a)/2, (A_1$b A_2$b)/2)
I used
pmap(list(A_1 , A_2), mean)
but got
Error in mean.default(.l[[1L]][[i]], .l[[2L]][[i]], ...) :
'trim' must be numeric of length one`
or
map2(A_1, A_2, mean)
Error in mean.default(.x[[i]], .y[[i]], ...) :
'trim' must be numeric of length one`
CodePudding user response:
Your mistake is in using the second matrix as trim=
argument of mean
whcih is the second. You need to c
oncatenate the matrices. Example:
mean(1:3, 2:4)
# Error in mean.default(1:3, 2:4) : 'trim' must be numeric of length one
mean(c(1:3, 2:4))
# [1] 2.5
As solution you may use Map
Map(\(x, y) (x y)/2, A_1, A_2)
# $a
# [,1] [,2] [,3] [,4]
# [1,] 5.5 7.5 9.5 11.5
# [2,] 6.5 8.5 10.5 12.5
#
# $b
# [,1] [,2] [,3] [,4]
# [1,] 3.5 5.5 7.5 9.5
# [2,] 4.5 6.5 8.5 10.5
Or, why not using arrays?
AA_1 <- array(unlist(A_1), dim=c(dim(A_1$a), length(A_1)))
AA_2 <- array(unlist(A_2), dim=c(dim(A_2$a), length(A_2)))
(AA_1 AA_2)/2
# , , 1
#
# [,1] [,2] [,3] [,4]
# [1,] 5.5 7.5 9.5 11.5
# [2,] 6.5 8.5 10.5 12.5
#
# , , 2
#
# [,1] [,2] [,3] [,4]
# [1,] 3.5 5.5 7.5 9.5
# [2,] 4.5 6.5 8.5 10.5
CodePudding user response:
In base R, We could use:
A <-list(A_1, A_2)
lapply(Reduce(\(x, y)Map(' ', x, y), A), '/', length(A))
$a
[,1] [,2] [,3] [,4]
[1,] 5.5 7.5 9.5 11.5
[2,] 6.5 8.5 10.5 12.5
$b
[,1] [,2] [,3] [,4]
[1,] 3.5 5.5 7.5 9.5
[2,] 4.5 6.5 8.5 10.5
This code is generic in that we can use to find the mean of several lists.
Note that A_1
and A_2
must have the same number of matrices, not necessarily 2. Can be 10 etc. Also note that each corresponding matrix has the same dimensions. Example below:
B_1 <- list(matrix(c(1,2,3,4), 2), matrix(c(1,3,4,2), 2),
matrix(c(1:10), 5), matrix(c(1:20), 5))
B_2 <- lapply(B_1, '*', 2) # In this case, its B_1 * 2
B_3 <- lapply(B_2, '*', 3) #
Now you could use the code provide above:
B <-list(B_1, B_2, B_3)
lapply(Reduce(\(x, y)Map(' ', x, y), B), '/', length(B))
CodePudding user response:
in base R:
item_names <- names(A_1)
structure(
lapply(item_names, function(name){
0.5 * (A_1[[name]] A_2[[name]])
## or, if you want the scalar mean:
## mean(A_1[[name]] A_2[[name]])
}),
names = item_names
)
#> $a
#> [,1] [,2] [,3] [,4]
#> [1,] 5.5 7.5 9.5 11.5
#> [2,] 6.5 8.5 10.5 12.5
#>
#> $b
#> [,1] [,2] [,3] [,4]
#> [1,] 3.5 5.5 7.5 9.5
#> [2,] 4.5 6.5 8.5 10.5