0

I have 2 matrices, one is species x traits and the second one is site x species (presence/absence). I need a third matrix sites x traits and in each column, I will have more than one value (all the values for all species of one site). How can I do this? Extract information of one matrix through another matrix? I am just a beginner in R...

I transposed the site x species and cbind the 2 matrices, but the result was all columns in one matrix...

trait <- read.table("trait_matrix_final.txt", head=T, sep="\t", dec=',', row.names=1)
com   <- read.table("community_matrix2.txt",  head=T, sep="\t", dec=',', row.names=1)
comt  <- t(com)
new   <- cbind(trait, comt)

And I tried to multiply both matrices, but it is not possible because I have continuous and categorical data.

EDIT:

Complementary comments: I have continuous (eg. body size) and categoricals variables (a daily activity with the values: nocturnal, diurnal or both). So, if I have 3 species in site 1, I want to obtain mean body size for these 3 species for site 1. For the categorical variable, if the 3 species have these values: species 1= nocturnal, species 2= nocturnal and species 3 =diurnal, the column will be something like that: nocturnal+diurnal or nocturnal.diurnal. My third matrix will have the same numbers of columns that in the 1st matrix (species x traits), but the traits are averaged across all species for the particular site.

gung - Reinstate Monica
  • 11,583
  • 7
  • 60
  • 79
EcoR
  • 23
  • 3

1 Answers1

0

It would be very useful to provide a reproducible example so SO community can help you in solving the problem.

AFTER EDIT:

You should store the data in an object of class matrix only if all entries of that matrix are of the same class (e.g. all numeric or all character). Because your first matrix has both numeric and character values it is better to format it as a data.frame. See this post for more info.

I will generate some data assuming you have 5 traits per species, 20 species per site, and 10 sites:

n.traits <- 5
n.species <- 20
n.sites <- 10

traits.names <- paste ("trait", 1:n.traits, sep = "_")
species.names <- paste ("spec", 1:n.species, sep = "_")
sites.names <- paste ("site", 1:n.sites, sep = "_")


# species*traits matrix
set.seed (4)
mat1 <- as.data.frame (matrix (replicate (n = n.traits, rnorm (n = n.species)), nrow = n.species, ncol = n.traits, dimnames = list (species.names, traits.names)))
mat1
set.seed (89)
mat1[, 2] <- sample (x = c ("diurnal", "nocturnal"), size = nrow (mat1), replace = T)
mat1

# site*species matrix
set.seed (6)
mat2 <- matrix (replicate (n = n.species, rbinom (n = n.sites, size = 1, prob = 0.8)), nrow = n.sites, ncol = n.species, dimnames = list (sites.names, species.names))
mat2

Following for loop will average traits across species for each site:

# sites*traits matrix
mat3 <- as.data.frame (matrix (NA, nrow = n.sites, ncol = n.traits, dimnames = list (sites.names, traits.names)))

for (i in 1:n.sites){
  spec_per_site_boolean <- mat2[i, ] == 1
  mat1_subset <- mat1[spec_per_site_boolean, ]
  
  for (j in 1:n.traits){
    if (is.numeric (mat1_subset[,j]))
      mat3[i,j] <- mean (mat1_subset[,j])
    else 
        mat3[i,j] <- paste (sort (unique(mat1_subset[,j])), collapse = ".")
  }
}
mat3

Note that the third matrix has the same number of columns as the first one (e.g. ncol (mat1) == ncol (mat3)), but it doesn't have the same number of rows (e.g. nrow (mat1) != nrow (mat3)).

Community
  • 1
  • 1
Newbie_R
  • 655
  • 7
  • 22
  • Thanks for the help Newbie_R! But it is not what I needed, maybe I didn't explain well. I edit my question... – EcoR Jun 27 '17 at 09:24