1

I have two lists of matrices (list A and list B, each matrix is of dimension 14x14, and list A contains 10 matrices and list B 11) and I would like to do a t test for each coordinate to compare the means of each coordinate of group A and group B. As a result I would like to have a matrix of dimension 14x14 which contains the p value associated with each t test.

Thank you in advance for your answers.

baptbapt
  • 23
  • 3
  • 4
    What do the rows and columns represent? Normally a t-test just compares two vectors of numbers. I'm not sure what the data being in a matrix would mean. It's easier to help you if you include a simple [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions. – MrFlick Oct 23 '21 at 18:28
  • each matrix represents a mouse brain image and each coordinate a pixel, and i have two groups of mouse, i want to know if some pixels are different between each group – baptbapt Oct 23 '21 at 19:23
  • Even if you can't give us your data, please *give us something*. Explaining what a structure is expected to be does not always exactly-match reality (since many new to R do not necessarily understand how R is really storing things underneath). MrFlick's comment has a link that includes many ways to provide sample data, the preferred and gold-standard is often `dput(x)` where `x` is a **minimal** and yet **representative** structure. In this case, it might be a list, length 2-3, each element being a matrix of some appropriate size. We don't need huge, just representative. Thanks. – r2evans Oct 23 '21 at 23:57
  • 1
    It sounds like you may just need to unwrap each matrix so that a 14x14 matrix becomes a 196 length vector (e.g. `as.vector(A[[1]])`) and compare the vectors. You probably are not just looking at overall differences but differences at particular locations so that using a paired t-test (subtracting the two vectors from one another) would make more sense. – dcarlson Oct 24 '21 at 03:35

1 Answers1

0

Here's a method using a for loop and then applying the lm() function.

First we'll generate some fake data as described in the question.

#generating fake matrices described by OP
listA <- vector(mode = "list", length = 10)
listB <- vector(mode = "list", length = 10)
for (i in 1:10) {
   listA[[i]] <-  matrix(rnorm(196),14,14,byrow = TRUE)
}
for (i in 1:11) {
  listB[[i]] <-  matrix(rnorm(196),14,14,byrow = TRUE)
}

Then we'll unwrap each matrix as described by dcarlson in a for loop.

Unwrapped.Mats <- NULL
for (ID in 1:10) {
  unwrapped <- as.vector(as.matrix(listA[[ID]])) #Unwrapping each matrix into a vector
  withID <- c(ID, "GroupA", unwrapped) #labeling it with ID# and which group it belongs to 
  UnwrappedCorMats <- rbind(Unwrapped.Mats, withID)
}
for (ID in 1:11) {
  unwrapped <- as.vector(as.matrix(listB[[ID]]))
  withID <- c(PID, "GroupB", unwrapped)
  UnwrappedCorMats <- rbind(UnwrappedCorMats, withID)
}

Then write and apply a function to run lm(). lm() is statistically equivalent to an unpaired t-test in this context but I'm using it to be more easily adapted into a mixed effect model if anyone wants to add mixed effects.

UnwrappedDF <- as.data.frame(UnwrappedCorMats)
lmPixel2Pixel <- function(i) { #defining function to run lm
  lmoutput <-   summary(lm(i ~ V2, data= UnwrappedDF)) 
  lmoutputJustP <- lmoutput$coefficients[2,4] #Comment out this line to return full lm output rather than just p value
}

Vector_pvals <- sapply(UnwrappedDF[3:length(UnwrappedDF)], lmPixel2Pixel)

Finally we will reform the vector into the same shape as the original matrix for more easily interpreting results

LM_mat.again <- as.data.frame(matrix(Vector_pvals, nrow = nrow(listA[[1]]), ncol = ncol(listA[[1]]), byrow = T)) 
colnames(LM_mat.again) <- colnames(listA[[1]]) #if your matrix has row or column names then restoring them is helpful for interpretation
rownames(LM_mat.again) <- colnames(listB[[1]])

head(LM_mat.again)

I'm sure there are faster methods but this one is pretty straight forward and I was surprised there weren't answers for this type of operation yet

Kirk Geier
  • 499
  • 8
  • 15