Related
I have created list of objects in R as follows:
set.seed(1234)
data <- matrix(rnorm(3*4,mean=0,sd=1), 3, 4)
results <- lapply(1:ncol(data), function(i) outer(data[, i], data[, i]))
all 4 list objects have dim=3x3. I also have the following matrix matr <- matrix(c(2,4,6,8),ncol=4), where each value corresponds to the above list objects.
Then, I use this equation matr[,1]*matr[,2]*results[[1]]*results[[2]] between the first two objects in order to create the below matrix
[,1] [,2] [,3]
[1,] 64.135122 2.6966755 12.4307531
[2,] 2.696676 0.1133865 0.5226732
[3,] 12.430753 0.5226732 2.4093448
How can I calculate the above equation for all all possible object combinations and save them to a new list?
We can use combn to create pairwise combination on the sequence of the list, extract the elements and do the multiplication
new_lst <- combn(seq_along(results), 2, \(i) matr[,i[1]] * matr[,i[2]] *
results[[i[1]]] * results[[i[2]]], simplify = FALSE)
names(new_lst) <- combn(seq_along(results), 2, paste, collapse="_")
-output
> new_lst
$`1_2`
[,1] [,2] [,3]
[1,] 64.135122 2.6966755 12.4307531
[2,] 2.696676 0.1133865 0.5226732
[3,] 12.430753 0.5226732 2.4093448
$`1_3`
[,1] [,2] [,3]
[1,] 5.775451 -1.2624981 -5.095849
[2,] -1.262498 0.2759787 1.113939
[3,] -5.095849 1.1139391 4.496217
$`1_4`
[,1] [,2] [,3]
[1,] 18.46710 -2.275650 -18.610758
[2,] -2.27565 0.280422 2.293352
[3,] -18.61076 2.293352 18.755530
$`2_3`
[,1] [,2] [,3]
[1,] 43.621251 -7.589849 -9.242303
[2,] -7.589849 1.320590 1.608108
[3,] -9.242303 1.608108 1.958223
$`2_4`
[,1] [,2] [,3]
[1,] 139.47970 -13.680683 -33.754187
[2,] -13.68068 1.341852 3.310735
[3,] -33.75419 3.310735 8.168537
$`3_4`
[,1] [,2] [,3]
[1,] 12.560327 6.404863 13.837154
[2,] 6.404863 3.266019 7.055953
[3,] 13.837154 7.055953 15.243778
I have a list of matrices in R as follows,
set.seed(1234)
data <- matrix(rnorm(3*4,mean=0,sd=1), 3, 4)
results <- lapply(1:ncol(data), function(i) outer(data[, i], data[, i]))
which results in:
[[1]]
[,1] [,2] [,3]
[1,] 1.4570077 -0.33487534 -1.3089918
[2,] -0.3348753 0.07696698 0.3008557
[3,] -1.3089918 0.30085569 1.1760127
[[2]]
[,1] [,2] [,3]
[1,] 5.502298 -1.0065968 -1.1870541
[2,] -1.006597 0.1841480 0.2171611
[3,] -1.187054 0.2171611 0.2560926
[[3]]
[,1] [,2] [,3]
[1,] 0.3303260 0.3141712 0.3244131
[2,] 0.3141712 0.2988064 0.3085474
[3,] 0.3244131 0.3085474 0.3186061
[[4]]
[,1] [,2] [,3]
[1,] 0.7921673 0.4247196 0.8886017
[2,] 0.4247196 0.2277129 0.4764227
[3,] 0.8886017 0.4764227 0.9967755
I want for each list object to sum the columns and find the minimum of these summation. For example min.results[[1]] = min(-0.186,0.042,0.167)=-0.186.
We may use sapply to loop over the list, get the column wise sum (colSums) and return with the minimum
sapply(results, \(x) min(colSums(x)))
-output
[1] -0.1868594 -0.7138005 0.9215250 1.1288552
Or using collapse
library(collapse)
fmin(dapply(results, colSums))
[1] -0.1868594 -0.7138005 0.9215250 1.1288552
Let's say I have a 5 by 7 matrix and a function f :
a <- matrix(rnorm(7*5),5,7)
f <- function(x,y) sum(x+y)
I would like to compute the matrix b whose element b[i,j] is equal to f(a[i,],a[j,]) without for loops. How could I do ?
You can use outer to apply a function to all possible combinations:
rowNums <- seq(nrow(a)) # vector with all row numbers
outer(rowNums, rowNums, Vectorize(function(x, y) sum(a[x, ] + a[y, ])))
[,1] [,2] [,3] [,4] [,5]
[1,] 6.319860 10.978305 6.911812 2.4609471 4.7021136
[2,] 10.978305 15.636751 11.570257 7.1193924 9.3605589
[3,] 6.911812 11.570257 7.503764 3.0528993 5.2940659
[4,] 2.460947 7.119392 3.052899 -1.3979658 0.8432008
[5,] 4.702114 9.360559 5.294066 0.8432008 3.0843673
Edit:
The calculations are more efficient if you calculate the rowSums before using outer. This code is shorter and faster:
rs <- rowSums(a)
outer(rs, rs, "+")
[,1] [,2] [,3] [,4] [,5]
[1,] 6.319860 10.978305 6.911812 2.4609471 4.7021136
[2,] 10.978305 15.636751 11.570257 7.1193924 9.3605589
[3,] 6.911812 11.570257 7.503764 3.0528993 5.2940659
[4,] 2.460947 7.119392 3.052899 -1.3979658 0.8432008
[5,] 4.702114 9.360559 5.294066 0.8432008 3.0843673
Edit 2:
A solution to your actual problem (see comments):
ta <- t(a) # transpose
apply(a, 1, function(x) colSums(abs(ta - x)))
[,1] [,2] [,3] [,4] [,5]
[1,] 0.000000 10.687579 10.933269 9.306339 7.763612
[2,] 10.687579 0.000000 7.465742 8.517358 7.847622
[3,] 10.933269 7.465742 0.000000 5.768676 6.851272
[4,] 9.306339 8.517358 5.768676 0.000000 6.687477
[5,] 7.763612 7.847622 6.851272 6.687477 0.000000
One way is to use expand.grid to create to subsetting indicies and use on this apply on this:
matrix(apply(expand.grid(seq(nrow(a)),seq(nrow(a))),1,
function(x) f(a[x[1],],a[x[2],])),nrow(a))
[,1] [,2] [,3] [,4] [,5]
[1,] 8.9116431 4.1067161 0.6589584 3.681561 3.207056
[2,] 4.1067161 -0.6982109 -4.1459686 -1.123366 -1.597871
[3,] 0.6589584 -4.1459686 -7.5937263 -4.571123 -5.045629
[4,] 3.6815615 -1.1233656 -4.5711232 -1.548520 -2.023026
[5,] 3.2070558 -1.5978712 -5.0456289 -2.023026 -2.497531
If I have a matrix mat1
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
it is possible via a very simple command to square all individual values by
mat1 * mat1
[,1] [,2] [,3]
[1,] 1 9 25
[2,] 4 16 36
Now, what I want to do is to create a new matrix where all values are computed by e^(old_value), e.g., e^1, e^2, e^3 and so forth. How can I do this?
exp computes the exponential function
> mat1 <- matrix(1:6, nrow=2)
> exp(mat1)
[,1] [,2] [,3]
[1,] 2.718282 20.08554 148.4132
[2,] 7.389056 54.59815 403.4288
I have a List, R=
[[1]]
[,1] [,2]
[1,] 100 0
[2,] 0 100
[[2]]
[,1] [,2]
[1,] 0.0006364031 0.2521204
[2,] 0.2521204236 99.9993643`
I'm suppose to do F %*% R
F
[1,] 1 -6.264917e-04
[2,] 1 1.575666e-04
As in F[1,] matrix multiplied with R[[1]], F[2,] matrix multiplied with R[[2]]
How should i go bout doing that?
Sorry. I think I was misunderstood. What I really want is F[1,]%*%R[[1]]%*%t(F[1,]) and F[2,]%*%R[[2]]%*%t(F[2,]) #Sven Hohenstein
mapply("%*%", as.data.frame(t(F)), R, SIMPLIFY = FALSE)
$V1
[,1] [,2]
[1,] 100 -0.06264917
$V2
[,1] [,2]
[1,] 0.0006761289 0.267877
Update
To answer your second question:
lapply(R, function(x) F %*% x %*% t(F))
[[1]]
[,1] [,2]
[1,] 100.00004 99.99999
[2,] 99.99999 100.00000
[[2]]
[,1] [,2]
[1,] 0.0003597493 0.0005083061
[2,] 0.0005083062 0.0007183373
Update
To answer your updated question:
mapply(function(x, y) y %*% x %*% as.matrix(y), R, as.data.frame(t(F)),
SIMPLIFY = FALSE)
[[1]]
[,1]
[1,] 100
[[2]]
[,1]
[1,] 0.0007183373
R <- list(matrix(c(100,0,0,100), 2), matrix(c(0.0006364031,0.2521204236,0.2521204,99.9993643), 2))
F <- matrix(c(1, 1, -6.264917e-04, 1.575666e-04), 2)
lapply(1:2, function(x) F[x,] %*% R[[x]])
## [[1]]
## [,1] [,2]
## [1,] 100 -0.06264917
##
## [[2]]
## [,1] [,2]
## [1,] 0.0006761289 0.267877
Just by doing it:
> F[1,]%*%R[[1]]
[,1] [,2]
[1,] 100 -0.06264917
> F[2,]%*%R[[2]]
[,1] [,2]
[1,] 0.0006761289 0.267877
Was there some particular way you wanted those stored?