Niedawno zacząłem pracować z R i Srvyr. Obecnie brzęk z następującym problemem:

Chciałbym obliczyć procenty w badanie ważone dla niektórych grup. Moja zmienna interesująca tutaj jest "połączenie". Wygląda na to, że moja ramka danych (DF) wygląda tak jak to:

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)

 survey_design <- df %>% 
              as_survey_design(ids = x, strata = y, weights = z)

 syv2 <- survey_design %>% 
 group_by(educ) %>%
 mutate(call_rate = n / sum(n)) %>%
 filter(call == 1) %>%
 select(educ, call_rate)

Kiedy wypróbuję ten kod, otrzymuję następujący błąd: Błąd w mutate_impl (.data, kropki): Błąd oceny: argument numeryczny do operatora binarnego.

Jednak bez użycia Srvyr nie otrzymuję tego błędu.

Próbowałem kodu dla kilku zmiennych.

1 Zasadniczo szukam najłatwiejszego sposobu obliczania wartości procentowych podgrup w całej kolumnach / zmiennych w Srvyr. Większość moich zmiennych jest binarna.

2 Czy istnieje elegancki sposób wykonania tej operacji dla wielu zmiennych. Chciałbym użyć zmiennej call przez cały czas, ale spojrzeć na różne podgrupy w innych zmiennych ({X1}} jest tylko jednym z przykładów)?

3 Czy można połączyć pakiet SRVYR ze stolikiem, aby obliczyć liczby bezwzględne / procenty i przedziały ufności 95%?

Jakieś sugestie?

1
msgh 21 luty 2019, 12:33

2 odpowiedzi

Najlepsza odpowiedź

Autor Srvyr tutaj (znalazł to za pośrednictwem wyszukiwania Vanity). Odpowiedź @symbolrush może unikać błędu, ale obliczyć podobne proporcje i wziąć pod uwagę masy ankiety, będziesz chciał użyć funkcji summarize() zamiast mutate() + filter()

Wierzę, co naprawdę chcesz:

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

Stworzone w dniu 2019-02-22 przez Pakiet REX (wersja 1.2.1)

Aktualizacja

@ Gregf: Czy można użyć kodu w ramach SYV3 i uzyskać te wyniki, dzieląc kolumny wyników w (a) całkowitej = Mężczyzna + Kobieta, (b) Kobieta i (c) Mężczyzna? - Msgh.

Przełączanie źródeł danych do jednego dołączonego do pakietu ankietowego (ponieważ przykładowe dane zabrało się z zmiennych). Zmienne, które zastępują te ze starego przykładu:

  • Stypty i sch.wide -> EDC & Wealth
  • API99 -> Zadzwoń
  • yr.rnd -> seks
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>

Stworzone w dniu 2019-02-28 przez Pakiet Reprex (V0.2.1)

Aktualizacja 2 : Czy można łączyć tableone + pakiet SRVYR, aby uzyskać bezwzględne liczby, procenty i przedziały ufności? Zdałem sobie sprawę, że byłoby to znacznie łatwiejsze.

1
msgh 4 kwiecień 2019, 10:54

Spróbuj zmienić mutate(call_rate = n() / sum(n()) i upewnij się, że wszystkie zmienne są reprezentowane numeryczne. Możesz wymusić zmienne znakowe zawierające liczby do reprezentacji numerycznej przy użyciu as.numeric na każdej kolumnie.


TL; DR:

Ponieważ n jest funkcją, wywołaniem n wewnątrz kodu zwraca closure (mniej więcej oznacza to, że zwraca źródło funkcji) zamiast faktycznie dzwonić do tej funkcji.

Spójrz na następujący minimalny przykład:

library(dplyr)
mtcars %>% mutate(freq = n / sum(n))

Zwraca błąd:

Błąd w mutate_impl (.data, kropki): Błąd oceny: nieprawidłowy "typ" (zamknięcie) argumentu.

Natomiast

library(dplyr)
mtcars %>% mutate(freq = n() / sum(n()))

Faktycznie wykonuje.

Lub po prostu wpisz dplyr::n w konsoli i widzisz ten korpus funkcji:

function () 
{
    abort("This function should not be called directly")
}
<environment: namespace:dplyr>
0
symbolrush 21 luty 2019, 09:43