如何在R中循环两个列表

问题描述

我有一个包含人口统计信息和问题的数据集。

DF<-(Participant = c(1,2,3,4,5,6,7,8,9,10)
Male = c(1,1,0)
Female = c(0,1)
Q1 = c(9,2)
Q2 = c(2,2)
Q3 = c(6,3))

我有两个列表(由列标题组成),一个是人口统计信息(男性,女性,年龄段等),另一个是带有相关答案的问题。

Demographic <- c(“Male”,“Female”,“Age_group_1”,“Age_group_2”…)
Questions<- c(“Q1”,“Q2”,Q3”,“Q4”…)

我需要一些类似的东西-如果人口统计列中的值等于1,则所有独立问题列中的总分都应为。但是我想这样做是一个循环,因此我对人口统计列表中的所有列(〜80)有单独的问题分数(〜300)。另外,我想保存输出。我不知道该怎么做,我自己也陷入了糟糕的编程循环中!

最终结果应类似于:

   M  F
Q1 20 21
Q2 16 16
Q3 23 18

我将不胜感激!

谢谢。

更新:

在朋友的帮助下,我找到了解决我的问题的方法。您如何使它更有效?

df.list <- list()
for(question in questions){
  question.df <- (DF[,lapply(.SD,sum,na.rm=T),by=question,.SDcols=c(demographic)])
  df.list <- append(df.list,question.df)}

list_new <- bind_cols(df.list,.id = "column_label")

解决方法

library(tidyr)
library(dplyr)

df <- data.frame(
    Participant = c(1,2,3,4,5,6,7,8,9,10),Male = c(1,1,0),Female = c(0,1),Q1 = c(9,2),Q2 = c(2,Q3 = c(6,3)
)

df %>% 
  mutate(sex = ifelse(Male == 1,"M","F")) %>%
  select(-Male,-Female) %>%
  pivot_longer(cols = starts_with("Q"),names_to = "Q") %>%
  group_by(sex,Q) %>%
  summarise(value = sum(value)) %>%
  pivot_wider(names_from = sex)

给予:

  Q         F     M
  <chr> <dbl> <dbl>
1 Q1       21    24
2 Q2       16    16
3 Q3       18    23
,

根据您要对输出执行的操作,另一种方法是使用tables::tabular(),它可以用于生成其他统计信息(例如百分比),以及自定义行标题和列标题。

我们将使用问题中提供的数据生成一个简单的表。

df <- data.frame(Participant = c(1,3))
df$sex <- ifelse(df$Male == 1,"F")
library(tables)
tabular((Q1 + Q2 + Q3)~Factor(sex)*(sum),data=df)

...以及输出:

> tabular((Q1 + Q2 + Q3)~Factor(sex)*(sum),data=df)
           
    sex    
    F   M  
    sum sum
 Q1 21  24 
 Q2 16  16 
 Q3 18  23 

处理多个人口统计变量

在对我的回答的评论中,有人问了一个问题:如何将tabular()与多个人口统计变量一起使用。

我们可以结合使用lapply()paste()substitute()来为`tabular()构建正确的公式表达式。

为说明该过程,我们将在上面列出的数据框中添加第二个人口统计学变量Income。然后,我们创建一个向量来表示将为其生成表的人口统计变量列表。最后,我们将向量与lapply()结合使用以生成表格。

df <- data.frame(Participant = c(1,Income = c(rep("low",5),rep("high",5)),3))
df$Sex <- ifelse(df$Male == 1,"F")
library(tables)
tabular((Q1 + Q2 + Q3)~Factor(Sex)*(sum),data=df)

demoVars <- c("Sex","Income")

lapply(demoVars,function(x){
        # generate a formula expression including the column variable
        # and use substitute() to render it correctly within tabular() 
        theExpr <- paste0("(Q1 + Q2 + Q3) ~ Factor(",x,")*(sum)")
        tabular(substitute(theExpr),data=df)
}) 

...以及输出:

> lapply(demoVars,function(x){
+         # generate a formula expression including the column variable
+         # and use substitute() to render it correctly within tabular() 
+         theExpr <- paste0("(Q1 + Q2 + Q3) ~ Factor(",")*(sum)")
+         tabular(substitute(theExpr),data=df)
+ })
[[1]]
           
    Sex    
    F   M  
    sum sum
 Q1 21  24 
 Q2 16  16 
 Q3 18  23 

[[2]]
              
    Income    
    high   low
    sum    sum
 Q1 16     29 
 Q2 15     17 
 Q3 13     28 

请注意,我们可以通过将表保存到输出对象并根据需要以可打印的格式呈现这些表来进一步增强解决方案。