Antti
Antti

Reputation: 1293

Filling a matrix from a dataframe with separate functions for diagonal and off-diagonal elements

I have a following problem where I have a dataframe (df):

df <- data.frame(inp = c("inp1", "inp2", "inp3"), A = c(1,2,3), B = c(1,2,3))

I need to construct a inp*inp square matrix from this dataframe that complies to certain formulas for diagonal and off-diagonal elements.

The diagonal elements are calculated as M[i,i] = A[i,i]^2 + B[i,i] and the off-diagonal elements as M[i,j] = A[i]*A[j] where i,j belong to set (inp1, inp2, inp3).

This is what I've got thus far - the function for calculating the off-diagonal values still escapes me.

 matFun <- function(df){
       x <- matrix(,
                   nrow = nrow(df),
                   ncol = nrow(df),
                   dimnames = list(df$inp, df$inp))

 #funOffDiag <- ???

 funDiag <- function(A,B){A^2 + B}
 d <- apply(df[c("A","B")], 1, function(y) funDiag(y["A"],y["B"]))
 diag(x) <- d
 x
 }

 matFun(df)

I need this solution as a function because I have to apply it to a longish list of dataframes.

Upvotes: 0

Views: 91

Answers (1)

Roland
Roland

Reputation: 132804

df <- data.frame(inp = c("inp1", "inp2", "inp3"), A = c(1,2,3), B = c(1,2,3))
mat <- tcrossprod(df$A)
colnames(mat) <- rownames(mat) <- df$inp
diag(mat) <- diag(mat) + df$B
#     inp1 inp2 inp3
#inp1    2    2    3
#inp2    2    6    6
#inp3    3    6   12

You should be able to create a function from this yourself ...

Upvotes: 2

Related Questions