我试图在某些组上使用tidyverse
工具(而不是for循环),并使用mvabund
包中的过程进行评估。
基本上,对于该过程,我首先需要一个仅包含数字列(物种丰富度)的数据框,然后将下游过程的变量分组。
但是,如果要对多个分组执行此操作,则需要包括分组变量。但是,当使用group_by
时,这些非数字变量仍然存在,该过程将无法运行。
如何使用dplyr
将数字变量传递给(mvabund)函数?
如果我只是一组,则过程如下:
library(tidyverse)
library(mvabund)
df <- data.frame(Genus.species1 = rep(c(0, 1), each = 10),
Genus.species2 = rep(c(1, 0), each = 10),
Genus.species3 = sample(1:100,20,replace=T),
Genus.species4 = sample(1:100,20,replace=T),
GroupVar1 = rep(c("Site1", "Site2"), each=2, times=5),
GroupVar2 = rep(c("AA", "BB"), each = 10),
GroupVar3 = rep(c("A1", "B1"), times=10))
df1 <- filter(df, GroupVar2 == "AA" & GroupVar3 == "A1") # get desired subset/group
df2 <- select(df1, -GroupVar1, -GroupVar2, -GroupVar3) # retain numeric variables
MVA.fit <- mvabund(df2) # run procedure
MVA.model <- manyglm(MVA.fit ~ df1$GroupVar1, family="negative binomial") # here I need to bring back GroupVar1 for this procedure
MVA.anova <- anova(MVA.model, nBoot=1000, test="wald", p.uni="adjusted")
MVA.anova$table[2,] # desired result
我尝试使用map
,do
,nest
等都是无效的。
如果没有分组,则有效
df.t <- as_tibble(df)
nest.df <- df.t %>% nest(-GroupVar1, -GroupVar2, -GroupVar3)
mva.tt <- nest.df %>%
mutate(mva.tt = map(data, ~ mvabund(.x)))
但此下一步不
mva.tt %>% mutate(MANY = map(data, ~ manyglm(.x ~ GroupVar1, family="negative binomial")))
此外,一旦我尝试删除总和为零或包含分组的列,一切都会失败。
是否有使用dplyr
和管道的明智方法?还是for loop
的答案?
编辑:
最初,我问这个问题:此外,当分成几组时,数据框将包含全为零的列,通常我会删除这些列。我可以将dplyr
个分组的变量数量改变吗?”,但评论显示,鉴于我的建议设置,这是不可能的。因此,我仍然对上述内容感兴趣。
答案 0 :(得分:2)
将步骤复制到一个函数中。还添加了组信息以在最后一行进行区分。
fun <- function(df) {
df1 <- select(df, -GroupVar1, -GroupVar2, -GroupVar3)
df3 <- df1 %>% select_if(~sum((.)) > 0)
MVA.fit <- mvabund(df3)
MVA.model <- manyglm(MVA.fit ~ df$GroupVar1, family="negative binomial")
MVA.anova <- anova(MVA.model, nBoot=1000, test="wald", p.uni="adjusted")
cbind(Group2 = df$GroupVar2[1], Group3 = df$GroupVar3[1], MVA.anova$table[2,])
}
将数据框分成几组并应用功能
library(tidyverse)
library(mvabund)
df %>%
group_split(GroupVar2, GroupVar3) %>%
map_dfr(fun)
#Time elapsed: 0 hr 0 min 0 sec
#Time elapsed: 0 hr 0 min 0 sec
#Time elapsed: 0 hr 0 min 0 sec
#Time elapsed: 0 hr 0 min 0 sec
# Group2 Group3 Res.Df Df.diff wald Pr(>wald)
#1 AA A1 3 1 1.028206 0.7432567
#2 AA B1 3 1 2.979169 0.1608392
#3 BB A1 3 1 2.330708 0.2137862
#4 BB B1 3 1 1.952617 0.2567433