автор srvyr здесь (нашел это с помощью тщеславного поиска).Ответ @symbolrush может избежать ошибки, но для расчета таких пропорций и учета весов опроса вы захотите использовать функцию summarize()
вместо mutate()
+ filter()
IВерьте, что вы действительно хотите:
df <- read.table(text=" educ call wealth x y z
A 1 0 1 20 12 0.9
B 3 0 2 21 13 0.8
C 5 1 3 22 14 1.1
D 2 0 2 23 12 0.8
E 1 1 1 24 16 0.92", header=T)
library(srvyr)
#>
#> Attaching package: 'srvyr'
#> The following object is masked from 'package:stats':
#>
#> filter
# required because your example dataset's weights aren't structured like real data
options(survey.lonely.psu="remove")
survey_design <- df %>%
as_survey_design(ids = x, strata = y, weights = z)
syv2 <- survey_design %>%
group_by(educ) %>%
summarize(call = survey_mean(call))
syv2
#> # A tibble: 4 x 3
#> educ call call_se
#> <int> <dbl> <dbl>
#> 1 1 0.505 0.250
#> 2 2 0 0
#> 3 3 0 0
#> 4 5 1 0
# Need to use something like purrr::map (or lapply) to iterate over different grouping variables
library(purrr)
syv3 <- map_dfr(c("educ", "wealth"), function(grp_var) {
survey_design %>%
group_by_at(grp_var) %>%
summarize(result = survey_mean(call)) %>%
rename(group_level = !!grp_var) %>%
mutate(group_var = grp_var) %>%
select(group_var, group_level, result, result_se)
})
syv3
#> # A tibble: 7 x 4
#> group_var group_level result result_se
#> <chr> <int> <dbl> <dbl>
#> 1 educ 1 0.505 0.250
#> 2 educ 2 0 0
#> 3 educ 3 0 0
#> 4 educ 5 1 0
#> 5 wealth 1 0.505 0.250
#> 6 wealth 2 0 0
#> 7 wealth 3 1 0
# This is almost a case where you could use dplyr's scoped functions to
# perform mean on a lot of vars, but only works if you're iterating over
# the variable you're calculating a mean on.
syv4 <- survey_design %>%
group_by(educ) %>%
summarize_at(vars(call, wealth), ~survey_mean(.))
syv4
#> # A tibble: 4 x 5
#> educ call call_se wealth wealth_se
#> <int> <dbl> <dbl> <dbl> <dbl>
#> 1 1 0.505 0.250 1 0
#> 2 2 0 0 2 0
#> 3 3 0 0 2 0
#> 4 5 1 0 3 0
Создано в 2019-02-22 с помощью представительного пакета (v0.2.1)
Обновление
@ GregF: возможно ли использовать код в syv3 и получать эти результаты при разбиении столбцов результатов на (а) всего = мужчина + женщина, (б) женщина и (с) мужчина?- msgh
Переключение источников данных на источник, включенный в пакет опроса (поскольку в данных примера не хватало переменных).Переменные, которые заменяют те из старого примера:
- stype & sch.wide -> Education & wealth
- api99 -> call
- yr.rnd -> sex
library(srvyr)
#>
#> Attaching package: 'srvyr'
#> The following object is masked from 'package:stats':
#>
#> filter
library(purrr)
data(api, package = "survey")
dstrata <- apistrat %>%
as_survey(strata = stype, weights = pw)
syv5 <- map_dfr(c("stype", "sch.wide"), function(grp_var) {
dstrata %>%
group_by_at(c(grp_var)) %>%
summarize(
result_yr = survey_mean(ifelse(yr.rnd == "Yes", api99, NA), na.rm = TRUE),
result_nonyr = survey_mean(ifelse(yr.rnd == "No", api99, NA), na.rm = TRUE),
result = survey_mean(api99)
) %>%
rename(group_level = !!grp_var) %>%
mutate_if(is.factor, as.character) %>%
mutate(group_var = grp_var) %>%
select(group_var, group_level, dplyr::starts_with("result"))
})
syv5
#> # A tibble: 5 x 8
#> group_var group_level result_yr result_yr_se result_nonyr result_nonyr_se
#> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
#> 1 stype E 528. 22.7 660. 14.2
#> 2 stype H 484 0 620. 15.9
#> 3 stype M 506. 49.6 615. 17.0
#> 4 sch.wide No 426. 17.8 611. 18.5
#> 5 sch.wide Yes 536. 22.2 654. 12.0
#> # ... with 2 more variables: result <dbl>, result_se <dbl>
Создано в 2019-02-28 пакетом представлением (v0.2.1)
Обновление2 : возможно ли объединить TableOne + пакет srvyr для получения абсолютных чисел, процентов и доверительных интервалов?Я понял, что это было бы намного проще.