'Creating a 3 by 1 matrix from three columns in a data frame and multiplying by a 2*3 in the correct order and applying to all the rows
I have a 23 constant complex matrix and create a 31 matric created from 3 columns of a data frame(this should be done for each row) and the result is going to be a 2*1 matric called N. This should be applied to all of the rows so I define a while loop. Then N[1,1] and N[2,1] are used to calculate the final thing, but I am not getting the result I want, I calculated Q from each row!!! I put Q like Q[i] inside the loop and still not the result I wanted.
library(dplyr)
library(tidyr)
library(readxl)
library(Matrix)
library(matlib)
library(readxl)
library(MASS)
c1 <- c(2+3i,1+2i,3+4i)
c2 <- c(1+4i,4+6i,7+1i)
c3 <- c(4+5i,2+2i,3+4i)
c4=2
df <- data.frame(c1,c2,c3)
print(df)
a1 <- matrix(c(1+2i,2+4i,5+1i,1+2i,5+4i,2+2i),nrow=3,ncol=2, byrow=T)
a_inv <- ginv(a1)
print(a_inv)
i <-1
while(i <= nrow(df)){
C <- matrix(c(df$c1[1],df$c2[1],df$c3[1]), nrow=3, ncol=1)
N <- a_inv %*% C
N1 <- N[1,1]
N2 <- N[2,1]
i=i+1
}
Q <-((N1+N2)*c4)
print(Q)
Solution 1:[1]
I would make a couple of empty lists to receive the while loop iteration results, made outside the loop:
N <- list()
lst_31_2 <- list() # your C
i = 1
while (i <= nrow(df)) {
lst_31_2[[i]] = matrix(c(df$c1[i], df$c2[i], df$c3[i]), nrow=3, ncol=1)
N[[i]] = a_inv %*% lst_31_2[[i]]
i= i+1
}
> str(N)
List of 3
$ : cplx [1:2, 1] 0.386+0.338i 0.781-0.169i
$ : cplx [1:2, 1] 0.393+0.602i 0.413-0.568i
$ : cplx [1:2, 1] 0.81+0.157i 0.452-0.351i
Then using the N values, a for loop:
Q <- list()
for (j in 1:nrow(df)) {
+ Q[[j]] <- (N[[j]][1,1] + N[[j]][2,1]) * c4
+ }
Q
[[1]]
[1] 2.333981+0.337864i
[[2]]
[1] 1.61165+0.067961i
[[3]]
[1] 2.524272-0.38835i
# or
unlist(Q)
[1] 2.333981+0.337864i 1.611650+0.067961i 2.524272-0.388350i
> unlist(Q)[1]
[1] 2.333981+0.337864i
> unlist(Q)[2]
[1] 1.61165+0.067961i
> unlist(Q)[3]
[1] 2.524272-0.38835i
Note the [[
to extract list values and [
for matrix. And I'll still say my best guess as I don't know what the expected value should be. The above 'while' could also be a for loop, which would simplify to one loop, this assuming df
and a_inv
in environment and C and Q lists:
for(k in 1:nrow(df)) {
lst_31_2[[k]] = matrix(c(df$c1[k], df$c2[k], df$c3[k]), nrow=3, ncol=1)
N[[k]] = a_inv %*% lst_31_2[[k]]
Q[[k]] <- (N[[k]][1,1] + N[[k]][2,1]) * c4
df$Q[k] <- Q[[k]]
}
> df
c1 c2 c3 Q
1 2+3i 1+4i 4+5i 2.333981+0.337864i
2 1+2i 4+6i 2+2i 1.611650+0.067961i
3 3+4i 7+1i 3+4i 2.524272-0.388350i
> Q
[[1]]
[1] 2.333981+0.337864i
[[2]]
[1] 1.61165+0.067961i
[[3]]
[1] 2.524272-0.38835i
ls()
[1] "a_inv" "a1" "c1" "c2" "c3" "c4"
[7] "df" "k" "lst_31_2" "N" "Q"
Because the objects were initialized as empty, outside the loop, they are all available after processing and can be removed rm(Q)
if they are cluttering up your workspace.
And I find building the steps like this, getting each part returning reasonably expected numbers, then next, then combining easier to later debug errors in my logic. So I first try to do it in the simplest base way I can.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |