With this dataframe:
table <- \"
trt rep ss d1 d4 d5 d6 d7
1 1 1 0 0 0 0 0
1 1 2 0 0 0 0 0
1 1 3 0
Thanks to @A.Webb, here's a way in base R:
aggregate(d[,4:8]>0~d$trt, FUN = mean)
# d$trt d1 d4 d5 d6 d7
# 1 1 0 0.2222222 0.4444444 0.5555556 0.5555556
# 2 2 0 0.0000000 0.0000000 0.3750000 0.5000000
Here was my original idea:
rowsum(+(d[-(1:3)] > 0), d$trt, na.rm=TRUE) /
rowsum(+!is.na(d[-(1:3)]), d$trt, na.rm=TRUE)
The +
is there because rowsum
only works with numbers, and not with logicals.
Using data.table
, something like this:
library(data.table)
d <- data.table(d)
d[,lapply(.SD,function(x) sum(x>0,na.rm=T)/sum(!is.na(x))),
.SDcols=grep("^d",names(d),val=T),
by=trt]
trt d1 d4 d5 d6 d7
1: 1 0 0.2222222 0.4444444 0.5555556 0.5555556
2: 2 0 0.0000000 0.0000000 0.3750000 0.5000000
We can use dplyr
library(dplyr)
d %>%
group_by(trt) %>%
summarise_each( funs(round(mean(.>0, na.rm=TRUE),2)), d1:d7)
# trt d1 d4 d5 d6 d7
# (int) (dbl) (dbl) (dbl) (dbl) (dbl)
#1 1 0 0.22 0.44 0.56 0.56
#2 2 0 0.00 0.00 0.38 0.50