dplyr:忽略函数输入的分组变量

时间:2019-03-13 15:17:40

标签: r dplyr

我试图在某些组上使用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

我尝试使用mapdonest等都是无效的。

如果没有分组,则有效

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个分组的变量数量改变吗?”,但评论显示,鉴于我的建议设置,这是不可能的。因此,我仍然对上述内容感兴趣。

1 个答案:

答案 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