为啥我的 dplyr group_by & summarise 不能正常工作? (名称与 plyr 冲突)

Posted

技术标签:

【中文标题】为啥我的 dplyr group_by & summarise 不能正常工作? (名称与 plyr 冲突)【英文标题】:Why are my dplyr group_by & summarize not working properly? (name-collision with plyr)为什么我的 dplyr group_by & summarise 不能正常工作? (名称与 plyr 冲突) 【发布时间】:2021-12-09 11:05:48 【问题描述】:

我有一个如下所示的数据框:

#df
ID  DRUG FED  AUC0t  Tmax   Cmax
1    1     0   100     5      20
2    1     1   200     6      25
3    0     1   NA      2      30 
4    0     0   150     6      65

以此类推。我想通过药物DRUG 和 FED STATUSFED 总结一些关于 AUC、Tmax 和 Cmax 的统计数据。我使用 dplyr。例如:对于 AUC:

CI90lo <- function(x) quantile(x, probs=0.05, na.rm=TRUE)
CI90hi <- function(x) quantile(x, probs=0.95, na.rm=TRUE)  

summary <- df %>%
             group_by(DRUG,FED) %>%
             summarize(mean=mean(AUC0t, na.rm=TRUE), 
                                 low = CI90lo(AUC0t), 
                                 high= CI90hi(AUC0t),
                                 min=min(AUC0t, na.rm=TRUE),
                                 max=max(AUC0t,na.rm=TRUE), 
                                 sd= sd(AUC0t, na.rm=TRUE))

但是,输出没有按 DRUG 和 FED 分组。它只给出了一行包含所有未分面的 DRUG 和 FED 的统计信息。

知道为什么吗?我怎样才能让它做正确的事?

【问题讨论】:

请查看此链接***.com/questions/21653295/dplyr-issues-with-group-by @akrun 非常感谢。我实际上对 dplyr 包很满意,但它看起来并不可靠! 顺便说一句,您不应该将您的函数标记为 CI95hi 和 CI95lo,即使用 95 而不是 90? @rnso 我使用的是 90% 置信区间。 这实际上是 plyr + dplyr + 偶尔使用其他库 (ggplot2 + xts) 的一个已知问题。还咬了我,也花了很长时间调试。 【参考方案1】:

或者你可以考虑使用data.table

library(data.table)
setDT(df)  # set the data frame as data table
df[, list(mean = mean(AUC0t, na.rm=TRUE),
          low = CI90lo(AUC0t), 
          high = CI90hi(AUC0t), 
          min = as.double(min(AUC0t, na.rm=TRUE)),
          max = as.double(max(AUC0t, na.rm=TRUE)), 
          sd = sd(AUC0t, na.rm=TRUE)),
   by=list(DRUG, FED)]

#    DRUG FED mean low high min  max sd
# 1:    1   0  100 100  100 100  100 NA
# 2:    1   1  200 200  200 200  200 NA
# 3:    0   1  NaN  NA   NA Inf -Inf NA
# 4:    0   0  150 150  150 150  150 NA
# Warning messages:
#   1: In min(AUC0t, na.rm = TRUE) :
#   no non-missing arguments to min; returning Inf
# 2: In max(AUC0t, na.rm = TRUE) :
#   no non-missing arguments to max; returning -Inf

【讨论】:

非常感谢。那也可以,但是,我改用了 ddply 。 ddply 看起来比 dplyr 更可靠。【参考方案2】:

我相信您在 dplyr 之后加载了 plyr,这就是为什么您得到的是整体摘要而不是分组摘要。

这就是最后加载 plyr 时发生的情况。

library(dplyr)
library(plyr)
df %>%
      group_by(DRUG,FED) %>%
      summarize(mean=mean(AUC0t, na.rm=TRUE), 
                low = CI90lo(AUC0t), 
                 high= CI90hi(AUC0t),
                 min=min(AUC0t, na.rm=TRUE),
                 max=max(AUC0t,na.rm=TRUE), 
                 sd= sd(AUC0t, na.rm=TRUE))

  mean low high min max sd
1  150 105  195 100 200 50

现在删除 plyr 并重试,您将获得分组摘要。

detach(package:plyr)
df %>%
      group_by(DRUG,FED) %>%
      summarize(mean=mean(AUC0t, na.rm=TRUE), 
                low = CI90lo(AUC0t), 
                 high= CI90hi(AUC0t),
                 min=min(AUC0t, na.rm=TRUE),
                 max=max(AUC0t,na.rm=TRUE), 
                 sd= sd(AUC0t, na.rm=TRUE))

Source: local data frame [4 x 8]
Groups: DRUG

  DRUG FED mean low high min max  sd
1    0   0  150 150  150 150 150 NaN
2    0   1  NaN  NA   NA  NA  NA NaN
3    1   0  100 100  100 100 100 NaN
4    1   1  200 200  200 200 200 NaN

【讨论】:

值得一提的是ggplot2 也可以产生这种效果——大概plyr 是一个依赖项。【参考方案3】:

aosmith 答案的一个变体,可能会帮助一些人。直接 R 直接调用 dplyr 的函数。一个包裹干扰另一个包裹时的好技巧。

df %>%
      dplyr::group_by(DRUG,FED) %>%
      dplyr::summarize(mean=mean(AUC0t, na.rm=TRUE), 
                low = CI90lo(AUC0t), 
                 high= CI90hi(AUC0t),
                 min=min(AUC0t, na.rm=TRUE),
                 max=max(AUC0t,na.rm=TRUE), 
                 sd= sd(AUC0t, na.rm=TRUE))

【讨论】:

破坏命名空间在 R XD 中被视为一种技巧【参考方案4】:

尝试使用 sqldf 是对数据进行分组的最佳方法且易于学习。 以下是您需要的示例。各种数据样本分组 sqldf 库非常有用。

install.packages("sqldf")
library(sqldf)
dat1 <- sqldf("select x,y,
            y/sum(y) as Z
            from dat
            group by x")

【讨论】:

【参考方案5】:

除了 dplyr,用户经常使用 ggplot 和它的 ggpubr 功能。事实上,它是另一个常用的包,与 dplyr 有一些不兼容。同理,如上所示,你可以使用dplyr::package,但如果它一直不起作用,就像我遇到的那样,只需分离库就足够了,

detach("package:ggpubr", unload = TRUE)

df %>%
  dplyr::group_by(DRUG,FED) %>%
  dplyr::summarize(mean=mean(AUC0t, na.rm=TRUE), 
            low = CI90lo(AUC0t), 
             high= CI90hi(AUC0t),
             min=min(AUC0t, na.rm=TRUE),
             max=max(AUC0t,na.rm=TRUE), 
             sd= sd(AUC0t, na.rm=TRUE))

【讨论】:

以上是关于为啥我的 dplyr group_by & summarise 不能正常工作? (名称与 plyr 冲突)的主要内容,如果未能解决你的问题,请参考以下文章

当我在`dplyr`之后加载`plyr`时,为啥汇总或变异不适用于group_by?

使用 dplyr、group_by 与 mutate() 或 summarise() & str_c() 或 paste() & 折叠连接字符串/行,但保持 NA & 所有字符

了解 dplyr 和 group_by

使用 dplyr、group_by 和折叠或汇总连接字符串/行,但保持 NA 值 [重复]

R使用dplyr group_by / sum for循环,作为连接列表输出

将 dplyr 函数 group_by() 与 cut() 一起使用