0

I want to calculate rowsums only if colnames (i.e. species) of my data frame match two arguments in a second attribute table. This means it shoul first match the name in a column of the attributes table AND have a certain entry in another column of the attribute table. However, the attribute table contains more species than the orginal data frame.

I tried :

# Species data from vegan package:
data(varespec, package = "vegan")

# create attributes table
attributes <- matrix(NA, length(varespec), 2)
attributes[,1] <- colnames(varespec)
attributes[,2] <- c(rep("MI",14),rep("PI",30))

# add species to the attribute table
x <- c("spec1","MI")
y <- c("spec2","PI")

attributes <- rbind(attributes, x, y)
row.names(attributes) <- c(1:46)

# calculate rowsums only for species contained in the attributes table 
# and having the entry "MI" in the attributes table
for (i in 1:44){
  for (j in 1:46){
    if ((colnames(varespec)[i] == attributes[j,1]) & (attributes[j,2] == "MI")) {
      apply(varespec,1,sum)
    }
  }}

But it always summed up the whole rows and not only the MI - species.

Thierry
  • 18,049
  • 5
  • 48
  • 66
Pharcyde
  • 397
  • 1
  • 3
  • 14

1 Answers1

0

This is easy to solve if you convert the dataset into a long format

library(dplyr)
library(tidyr)
data(varespec, package = "vegan")
attributes <- data.frame(
  Species = c(colnames(varespec), "spec1", "spec2"),
  Attribute = c(rep(c("MI", "PI"), c(14, 30)), "MI", "PI")
)
varespec %>% 
  add_rownames("ID") %>% 
  gather(Species, Value, -ID) %>% #convert to long format
  inner_join(attributes, by = "Species") %>% 
  filter(Attribute == "MI") %>% 
  group_by(ID) %>% 
  summarise(Total = sum(Value))
Thierry
  • 18,049
  • 5
  • 48
  • 66
  • Thank you very much for the fast answer. Now i have to spend some time studying what is actually happening here. These %>% is totally new to me, it feels like this is an much more professional programming style, than i am used to. Thanks a lot, I think I can learn a lot from this answer. – Pharcyde Oct 07 '15 at 14:37