微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

这个 dplyr group_by 代码的 Base R 等价物是什么?

如何解决这个 dplyr group_by 代码的 Base R 等价物是什么?

The R4DS book 具有以下代码块:

library(tidyverse)
by_age2 <- gss_cat %>%
  filter(!is.na(age)) %>%
  count(age,marital) %>%
  group_by(age) %>%
  mutate(prop = n / sum(n))

在基本 R 中是否有与此代码等效的简单代码filter 可以替换为 gss_cat[!is.na(gss_cat$age),],但之后我遇到了麻烦。这显然是 bytapplyaggregate 的工作,但我一直找不到正确的方法by(gss_2,with(gss_2,list(age,marital)),length) 是朝着正确方向迈出的一步,但结果很糟糕。

解决方法

我们可以在 proportions 删除 table (subset) 和 NA 列之后在 complete.cases 输出上使用 select

数据来自 forcats 包。所以,加载包并获取数据

library(forcats)
data(gss_cat)

使用上面提到的table/proportions

by_age2_base <- proportions(table(subset(gss_cat,complete.cases(age),select = c(age,marital))),1)

-输出

head(by_age2_base,3)
    marital
age    No answer Never married   Separated    Divorced     Widowed     Married
  18 0.000000000   0.978021978 0.000000000 0.000000000 0.000000000 0.021978022
  19 0.000000000   0.939759036 0.000000000 0.012048193 0.004016064 0.044176707
  20 0.000000000   0.904382470 0.003984064 0.007968127 0.000000000 0.083665339

-与 OP 的输出进行比较

head(by_age2,3)
# A tibble: 3 x 4
# Groups:   age [2]
    age marital           n   prop
  <int> <fct>         <int>  <dbl>
1    18 Never married    89 0.978 
2    18 Married           2 0.0220
3    19 Never married   234 0.940 

如果我们需要'long'格式的输出,用tabledata.frame转换成as.data.frame

by_age2_base_long <- subset(as.data.frame(by_age2_base),Freq > 0)

或者另一个选项是aggregate/ave(使用R 4.1.0

subset(gss_cat,marital)) |> 
    {\(dat) aggregate(cbind(n = age) ~ age + marital,data = dat,FUN = length)}() |> 
   transform(prop = ave(n,age,FUN = \(x) x/sum(x)))

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。