我的数据框看起来像:
POP<-c(rep("POP1",6), rep("POP2",6), rep("POP3", 6))
IID<-c(rep("POP1_1", 2), rep("POP1_2",2), rep("POP1_3", 2), rep("POP2_1",2), rep("POP2_2",2), rep("POP2_3",2), rep("POP3_1",2), rep("POP3_2",2),rep("POP3_3",2))
Site1<-c(36, 42, 32, 32, 48, 42, 36, 36, 48, 42, 36, 48, 28, 32, 32, 32, 48, 32)
Site2<-c(10, 8, 10, 16, 16, 10, 10, 10, 16, 10, -9, -9, 16, 8, 10, 10, 8, 8)
dat<-cbind(POP, IID, Site1, Site2)
拥有更多网站列,以及更多POP组。我希望按列进行操作,对于列中的每个不同条目,我想要一个新列来包含该条目的频率,通过POP列聚合。 -9表示缺失值。我不希望这些构成一个列,或者为频率做出贡献。
最终,上面的数据看起来像:
dat
POP Site1_28 Site1_32 Site1_36 Site1_42 Site1_48 Site2_8 Site2_10 Site2_16
POP1 0 0.333 0.167 0.333 0.166 0.167 0.5 0.333
POP2 0 0 0.5 0.167 0.333 0 0.75 0.25
POP3 0.167 0.667 0 0 0.167 0.5 0.333 0.167
我猜测我会使用table()和aggregate()来查看lapply(),但我真的不知道从哪里开始。
谢谢!
答案 0 :(得分:1)
我认为这应该做你想要的。首先,我们进行一些数据操作,以便调用table
。然后,我们迭代这两列,按每个prop.table
值为网站执行POP
。最后,我们使用rbind
和cbind
来合并数据。
#create data.frame
dat<-data.frame(POP, IID, Site1, Site2,
stringsAsFactors = FALSE)
#identify columns containing 'Site'
site_col_names <- names(dat)[grep(pattern = 'Site', x = names(dat))]
#for each site column, recode -9 as NA, and then paste
for(i in site_col_names){
dat[i] <- factor(sapply(dat[i], function(x)
ifelse(x == -9, NA, paste0(i,'_',x))))
}
#iterate over columns, calculate prop.table
do.call('cbind',
lapply(site_col_names, function(n){
do.call('rbind',
by(dat, dat$POP, function(d) prop.table(table(d[n]))))
}))
Site1_28 Site1_32 Site1_36 Site1_42 Site1_48 Site2_10 Site2_16 Site2_8
POP1 0.0000000 0.3333333 0.1666667 0.3333333 0.1666667 0.5000000 0.3333333 0.1666667
POP2 0.0000000 0.0000000 0.5000000 0.1666667 0.3333333 0.7500000 0.2500000 0.0000000
POP3 0.1666667 0.6666667 0.0000000 0.0000000 0.1666667 0.3333333 0.1666667 0.5000000