【问题标题】:filter inside dplyr's summarise在 dplyr 的汇总中过滤
【发布时间】:2018-08-06 16:52:51
【问题描述】:

我想在dplyr 包中使用filter 或summarise 中的类似功能。所以我有一个数据框(例如mtcars),我需要按因子分组(例如cyl),然后为每个cyl 类型计算一些统计数据和wt 总数的百分比—> wt.pc .

问题是我如何子集/过滤summarise 函数内的wt 列以获得百分比但没有最后10 行?

我试过这段代码,但它返回NA:(

mtcars %>%
  group_by(cyl) %>%
  summarise(wt = round(sum(wt)),
            wt.pc = sum(wt) * 100 / sum(mtcars[, 6]),
            wt.pc.short = sum(wt[1:22]) * 100 / sum(mtcars[1:22, 6]),
            drat.max = round(max(drat)))

# A tibble: 3 x 5
    cyl    wt wt.pc wt.pc.short drat.max
  <dbl> <dbl> <dbl>       <dbl>    <dbl>
1     4    25  24.3          NA        5
2     6    22  21.4          NA        4
3     8    56  54.4          NA        4

wt.pc.short — 每个 cyl 的总和百分比(wt),用于较短的数据帧 mtcars[1:22,]

【问题讨论】:

  • head(x,n=-10) 给出了向量 x 中除最后 10 个值之外的所有值,但 mtcars 中的一组 (cyl==6) 只有 7 个值,所以这不起作用。 (您的1:22 缺少dplyr 的分组点。)

标签: r filter dplyr


【解决方案1】:

这样的?

mtcars %>%
  mutate(id = row_number()) %>% 
  group_by(cyl) %>%
  summarise(wt_new = round(sum(wt)), # note the change in name here!
            wt.pc = sum(wt) * 100 / sum(mtcars[, 6]),
            wt.pc.short = sum(wt[id<23]) * 100 / sum(mtcars[1:22, 6]),
            drat.max = round(max(drat)))

# A tibble: 3 x 5
    cyl wt_new wt.pc wt.pc.short drat.max
  <dbl>  <dbl> <dbl>       <dbl>    <dbl>
1     4     25  24.3        22.7        5
2     6     22  21.4        25.8        4
3     8     56  54.4        51.6        4

这里的重要部分是,当您在对summarize 的调用中分配wt 时,所有后续对wt 的引用都将采用先前分配的wt,而不是原来的wt。因此,wt[1:22] 之类的声明有些问题。你可以在这里看到:

mean(mtcars[,"mpg"])
# [1] 20.09062
var(mtcars[,"mpg"])
# [1] 36.3241
mtcars %>% summarise(var_before = var(mpg),  
                     mpg = mean(mpg), 
                     var_after = var(mpg))

#  var_before      mpg var_after
# 1    36.3241 20.09062        NA

【讨论】:

  • 非常感谢您的解决方案和解释。顺便说一句,有没有更好的方法来计算百分比?我对您在第 7 行的评论感到惊讶
  • 不,在这种情况下,这几乎是如何做到的。其他任何东西都会是不同的百分比。
【解决方案2】:

我认为你可以这样做。首先我们计算组内的行号,如果max(row_number) &gt; 10那么我们有足够的观察来删除最后10行,在这种情况下我们过滤到max(ID)-9(即删除最后10行),否则ID==ID返回true并且不会删除任何内容。

mtcars %>% group_by(cyl) %>% 
  mutate(ID = row_number()) %>% 
  filter(if (max(ID) > 10) ID < (max(ID) - 9) else ID == ID)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2019-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多