如何解决这个 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),]
,但之后我遇到了麻烦。这显然是 by
、tapply
或 aggregate
的工作,但我一直找不到正确的方法。 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'格式的输出,用table
将data.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 举报,一经查实,本站将立刻删除。