Точные пропорции в таблице сопряженности dplyr - PullRequest
0 голосов
/ 10 июня 2018

Я искал способ сделать это в течение нескольких дней и не нашел программного решения.Я моделирую аккуратные данные в R, используя Dplyr.Мне нужно иметь возможность создать таблицу непредвиденных расходов, которая включает пропорции.Я следовал за решением нескольких других постов, но с аккуратными данными рассчитанные пропорции неверны.Хотя я знаю, что могу использовать prop.table для этих вычислений, я бы хотел остаться в Dplyr из-за остальной части работы, которую необходимо выполнить в моем рабочем процессе.Это сложный опрос, и переменные охватывают множество столбцов, что делает подход оптимальным.

Я воссоздаю проблему с некоторыми смоделированными данными:

library(tidyverse)

set.seed(0520)

# Create a data frame with three brands
# Simulated survey data for brand familiarity
# A zero means respondent is unfamiliar with brand
# A one means they are familiar with the brand

brands <- data.frame(
  a = rbinom(n = 100, size = 1, prob = .3),
  b = rbinom(n = 100, size = 1, prob = .6),
  c = rbinom(n = 100, size = 1, prob = .55)
)

# Create factors for each

brands$a <- factor(brands$a, labels = c("Unfamiliar", "Familiar"))
brands$b <- factor(brands$b, labels = c("Unfamiliar", "Familiar"))
brands$c <- factor(brands$c, labels = c("Unfamiliar", "Familiar"))

brands %>% 
  select(a:c) %>% 
  gather(brand, score) %>% 
  filter(score == "Familiar") %>% 
  group_by(Brand = brand) %>% 
  summarize(n = n()) %>% 
  mutate(Prop = n/sum(n))

Как вы заметите, этот кодрассчитывает долю респондентов, которые были знакомы с брендом C, как 46%, что неверно.Оно должно составлять 57%.

Мой текущий обходной путь - вводить число строк в исходной таблице (100) в моей инструкции mutate.Но я бы хотел, если это возможно, использовать программный способ сделать это.

Заранее благодарен за указание в правильном направлении.

Ответы [ 2 ]

0 голосов
/ 10 июня 2018

, поскольку у вас есть только два уровня, вы можете использовать colMeans

brands%>%
  mutate_all(~as.numeric(.)-1)%>%
  colMeans()
   a    b    c 
0.19 0.49 0.57 

или даже

 brands%>%
    summarise_all(~mean(as.numeric(.)-1))
     a    b    c
1 0.19 0.49 0.57

, или вы можете напрямую сделать

brands%>%
    summarise_all(~mean(.=="Familiar"))
     a    b    c
1 0.19 0.49 0.57
0 голосов
/ 10 июня 2018

Чтобы определить долю каждой марки со значением Familiar, вы не можете сбросить строки Unfamiliar с filter, так как они вносят вклад в общее количество внизу.Таким образом, вам нужно рассчитать количество Familiar значений по-другому, например, sum(score == 'Familiar'):

library(tidyverse)
set.seed(0520)

brands <- data.frame(
  a = rbinom(n = 100, size = 1, prob = .3),
  b = rbinom(n = 100, size = 1, prob = .6),
  c = rbinom(n = 100, size = 1, prob = .55)
) %>% 
    mutate_all(~factor(.x, labels = c("Unfamiliar", "Familiar")))

brands %>% 
    gather(brand, score) %>% 
    group_by(brand) %>% 
    summarize(n_familiar = sum(score == 'Familiar'), 
              prop = n_familiar / n())
#> # A tibble: 3 x 3
#>   brand n_familiar  prop
#>   <chr>      <int> <dbl>
#> 1 a             19 0.19 
#> 2 b             49 0.49 
#> 3 c             57 0.570

Теперь n() - это количество строк в каждой группе (100) и n_familiarколичество Familiar строк.

...