我有一个数据框,其中包含对26个变量(问题)的二元调查响应(是/否)的数千个响应;每个参与者还具有性别变量(男性/女性)。我想创建一个表格,列出26个问题中每个回答“是”的比例,并分别为男性和女性。
通过使用下面的代码,我可以实现所需的结果,但是当涉及26个变量时,它似乎效率很低。我确信有更好的方法可以执行此操作,也许使用*apply
系列函数之一,但是我不确定如何执行此操作,甚至不确定从哪里开始。非常感谢您的帮助。
df <- data.frame(Sex = c(0,1,1,0,1,0,1,1,0,0), Q1 = c(1,1,0,1,0,0,1,1,0,1),
Q2 = c(0,1,1,0,0,0,1,0,0,0),
Q3 = c(0,1,0,0,1,1,0,1,0,1))
df$Sex <- factor(df$Sex, levels = c(0, 1), labels = c("Female", "Male"))
table1 <- 100*prop.table(table(df$Q1[df$Sex == "Female"]))
table2 <- 100*prop.table(table(df$Q2[df$Sex == "Female"]))
table3 <- 100*prop.table(table(df$Q3[df$Sex == "Female"]))
m.table <- rbind(table1, table2, table3)
m.table <- m.table[,c(2)]
table4 <- 100*prop.table(table(df$Q1[!df$Sex == "Female"]))
table5 <- 100*prop.table(table(df$Q2[!df$Sex == "Female"]))
table6 <- 100*prop.table(table(df$Q3[!df$Sex == "Female"]))
f.table <- rbind(table4, table5, table6)
f.table <- f.table[,c(2)]
mf.table <- cbind(m.table, f.table)
答案 0 :(得分:2)
由于您的回答是“ 1/0”,因此我们可以回答mean
个问题列。在基数R中,我们可以使用aggregate
aggregate(.~Sex, df, mean)
# Sex Q1 Q2 Q3
#1 0 0.6 0.0 0.4
#2 1 0.6 0.6 0.6
使用dplyr
的一种方法是去group_by
Sex
并通过取mean
各个问题列来计算1的比率
library(dplyr)
df %>%
group_by(Sex) %>%
summarise_at(vars(starts_with("Q")), mean)
# Sex Q1 Q2 Q3
# <dbl> <dbl> <dbl> <dbl>
#1 0 0.6 0 0.4
#2 1 0.6 0.6 0.6
或者使用tidyr
并进行一些重塑
library(dplyr)
library(tidyr)
df %>%
gather(question, value, -Sex) %>%
group_by(Sex, question) %>%
summarise(yesratio = mean(value)) %>%
spread(question, yesratio)
答案 1 :(得分:1)
另一种解决方案(不一定比@RonakShah的解决方案更干净):将数据从宽到长整形,在所有三列上计算一张表,计算比例,以“是”比例将比例缩放100:
df_m <- reshape2::melt(df,id.vars="Sex",
variable.name="Variable",
value.name="Response")
tt1 <- with(df_m,table(Sex,Variable,Response))
tt2 <- prop.table(tt1,margin=c(1,2))
t(tt2[,,"1"]*100)
答案 2 :(得分:1)
我们可以使用by
中的base R
by(df[-1], df$Sex, colMeans)
#df$Sex: Female
# Q1 Q2 Q3
#0.6 0.0 0.4
------------------------------------------------------------------------------------------------------------
#df$Sex: Male
# Q1 Q2 Q3
#0.6 0.6 0.6
或者正如OP提到的有效使用,选项为data.table
library(data.table)
setDT(df)[, lapply(.SD, mean), Sex]
# Sex Q1 Q2 Q3
#1: Female 0.6 0.0 0.4
#2: Male 0.6 0.6 0.6