总结但保持长度可变(dplyr)
Posted
技术标签:
【中文标题】总结但保持长度可变(dplyr)【英文标题】:Summarise but keep length variable (dplyr) 【发布时间】:2019-03-15 17:10:39 【问题描述】:基本 dplyr 问题...受访者可以选择他们使用的多家公司。例如:
library(dplyr)
test <- tibble(
CompanyA = rep(c(0:1),5),
CompanyB = rep(c(1),10),
CompanyC = c(1,1,1,1,0,0,1,1,1,1)
)
test
如果这是一个强制选择问题 - 即受访者只能选择一个 - 我会为基本汇总表执行以下操作:
test %>%
summarise_all(funs(sum), na.rm = TRUE) %>%
gather(Response, n) %>%
arrange(desc(n)) %>%
mutate("%" = round(100*n/sum(n)))
但是请注意,“%”列不是我想要的。我正在寻找每个单独的响应选项占总受访者的比例(因为他们可以做出多项选择)。
我尝试在summarise_all
命令之前添加mutate(totalrows = nrow(.)) %>%
。这将允许我在以后的mutate
命令中使用该变量作为分母。但是,summarise_all
消除了“totalrows”变量。
另外,如果有更好的方法可以做到这一点,我愿意接受。
【问题讨论】:
我不确定我是否理解您的问题,但您不能只取每列的平均值来获得每个单独响应选项的总受访者比例吗?我的意思是,如果五分之三的人选择 A 公司,那么您的数据可能看起来像c(1, 0, 1, 1, 0)
。如果取平均值,则为 0.6,即选择该选项的受访者比例。
这完全可行 - 想多了。请切换回答,我会接受的。
如果你想继续想太多,你可以把sum(n)
改成nrow(test)
,所以代码是test %>% summarise_all(funs(sum), na.rm = TRUE) %>% gather(Response, n) %>% arrange(desc(n)) %>% mutate("%" = round(100*n/nrow(test)))
【参考方案1】:
要获得在变量为二元时选择选项的受访者比例,您可以取平均值。要对您的测试数据执行此操作,您可以使用sapply
:
sapply(test, mean)
CompanyA CompanyB CompanyC
0.5 1.0 0.8
如果您想以更复杂的方式执行此操作(假设您的数据不是二进制编码的,而是存储为 1
和 2
),您可以使用以下方法:
test %>%
gather(key='Company') %>%
group_by(Company) %>%
summarise(proportion = sum(value == 1) / n())
# A tibble: 3 x 2
Company proportion
<chr> <dbl>
1 CompanyA 0.5
2 CompanyB 1
3 CompanyC 0.8
【讨论】:
我不知道编码为 1 或 2 的变量。谢谢!【参考方案2】:如果您将所有函数放在 summarise 中的列表中,那么这将起作用。不过,你需要做一些快速整理。
test %>%
summarise_all(
list(
rows = length,
n = function(x)sum(x, na.rm = T),
perc = function(x)sum(x,na.rm = T)/length(x)
)) %>%
tidyr::gather(Response, n) %>%
tidyr::separate(Response, c("Company", "Metric"), '_') %>%
tidyr::spread(Metric, n)
你会得到这个
Company n perc rows
<chr> <dbl> <dbl> <dbl>
1 CompanyA 5 0.5 10
2 CompanyB 10 1 10
3 CompanyC 8 0.8 10
【讨论】:
【参考方案3】:这是使用tidyr::gather
的解决方案:
test %>%
gather(Company, response) %>%
group_by(Company) %>%
summarise(`%` = 100 * sum(response) / n())
【讨论】:
以上是关于总结但保持长度可变(dplyr)的主要内容,如果未能解决你的问题,请参考以下文章