dplyr列联表中的准确比例

时间:2018-06-10 17:11:35

标签: r dplyr tidyr

我一直在寻找一种方法来做这些,并且没有找到一个程序化的解决方案。我使用Dplyr在R中建模整洁的数据。我需要能够创建一个包含比例的列联表。我已经按照其他几个帖子的解决方案,但是通过整洁的数据,计算出的比例是错误的。虽然我知道我可以使用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%。

我目前的解决方法是在mutate语句中修改原始表(100)中的行数。但是如果可能的话,我会喜欢以编程的方式来做这件事。

提前感谢我指出了正确的方向。

2 个答案:

答案 0 :(得分:1)

要查找具有Familiar值的每个品牌的比例,您不能删除Unfamiliarfilter,因为它们会占用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()

现在n_familiar是每个组中的行数(100),Familiar是{{1}}行的数量。

答案 1 :(得分:0)

由于您只有两个级别,因此可以使用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