To solve this problem you must first convert your data frame to a long format.
Your file:
site sample1 sample2 sample3 sample4 sample5 sample6
Site1 A T C T W W
Site2 A W M N N N
Site3 R A A A N A
Site4 A T C W T T
Site5 G A N N A A
Code:
> library(tidyr)
> library(dplyr)
> mydf = read.table('biostar.csv', header=T)
> mydf.long = mydf %>% gather(sample, genotype, -site)
> mydf.long %>% head
site sample genotype
1 Site1 sample1 A
2 Site2 sample1 A
3 Site3 sample1 R
4 Site4 sample1 A
5 Site5 sample1 G
6 Site1 sample2 T
7 Site2 sample2 W
8 Site3 sample2 A
EDIT: if you prefer the reshape2 library instead of tidyr:
> library(reshape2)
> mydf.long = mydf %>%
melt(id.vars=c('site'), variable.name='sample') %>%
rename(genotype=value)
Now I am not really sure about what your function must do, but the principle is to use group_by and summarise from dplyr.
> mysummary = mydf.long %>%
group_by(sample) %>%
summarise(
totN = sum(genotype == 'N', na.rm=T), # in alternative length(site[genotype=='N'])
knownSitesN = sum(genotype != 'N', na.rm=T),
heteroSitesN = sum (genotype %in% c("R", "Y", "M", "K", "S", "W"), na.rm=T),
percPolyM = heteroSitesN/knownSitesN
)
> mysummary
sample totN knownSitesN heteroSitesN percPolyM
1 sample1 0 5 1 0.2000000
2 sample2 0 5 1 0.2000000
3 sample3 1 4 1 0.2500000
4 sample4 2 3 1 0.3333333
5 sample5 2 3 1 0.3333333
6 sample6 1 4 1 0.2500000
Again, instead of doing operations on columns, you must reformat the dataframe to a long format, so that the sites are on the rows instead. Then you can use the standard group_by operations in dplyr to calculate your summaries. You never need to iterate on columns in R.
Please post example data.
An example is as follows:
This contains six sample columns, not five.
use a character matrix instead of a data frame