dplyr: игнорировать группирующие переменные для ввода функции - PullRequest
0 голосов
/ 13 марта 2019

Я пытаюсь использовать tidyverse инструменты (вместо циклов) для некоторых групп, которые будут оцениваться с помощью процедур из пакета 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 ответ?

Edit: Первоначально я спрашивал об этом: Кроме того, когда разбито на группы, фрейм данных будет содержать столбцы с нулевыми значениями, обычно я удаляю их. Могу ли я иметь dplyr группировок, которые различаются по количеству переменных? ", Но комментарии показали, что это невозможно, учитывая мою предложенную настройку. Поэтому я все еще заинтересован в вышеприведенном.

1 Ответ

2 голосов
/ 13 марта 2019

Скопировал шаги в функцию.Также добавлена ​​информация о группе для дифференциации в последней строке.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...