【问题标题】:R, dplyr: Using dynamic variables to access a table nameR、dplyr:使用动态变量访问表名
【发布时间】:2021-01-09 14:52:00
【问题描述】:

我正在尝试在 for 循环中使用动态变量来访问表名。 SO 上的其他问题(例如hereherehere)似乎与使用动态变量访问列名有关。我正在使用 R v4.0.3 和 dplyr v1.0.2。

基本上,我从 .sav (SPSS) 文件导入,并试图将 400 多列拆分为较小的数据框,其中包含每个调查问题的信息。这部分有效,但我想做一些事情,比如为每个新数据框添加一个平均列。我目前正在尝试在分段 for 循环中执行此操作,但我无法使其正常工作。 (我也很乐意为另一个 for 循环或列表或其他内容中的每个新数据帧单独执行此操作,但如果我无法让另一个工作,我也看不出这将如何工作!)

稍微简化一下,原始文件中的列被命名为 QX.Y_Z,其中 Z 是 X 块中问题 Y 中的项目。

一些虚拟数据,设置2个问题的(sav-type)数据框,每个问题有两个项目:

    mydata=tibble(Q6.1_1_1=as.numeric(c(2, 1, 3, 1, 2, 3, 1, 3, 2, 1, 1, 1, 2, 2)),
              Q6.1_1_2=as.numeric(c(1, 3, 1, 1, 1, 2, 3, 3, 1, 3, 1, 1, 1, 2)),
              Q7.1_1_1=as.numeric(c(1, 2, 1, 2, 1, 3, 3, 1, 2, 3, 2, 1, 3, 2)),
              Q7.1_1_2=as.numeric(c(3, 1, 3, 1, 2, 1, 3, 2, 3, 1, 3, 1, 1, 3)),
              )
    var_label(mydata$Q6.1_1_1)<-"Rate your effort - before."
    var_label(mydata$Q6.1_1_2)<-"Rate your effort - before." 
    var_label(mydata$Q7.1_1_1)<-"Rate your enthusiasm - before." 
    var_label(mydata$Q7.1_1_2)<-"Rate your enthusiasm - after." 
    val_labels(mydata$Q6.1_1_1)<-c(Low=1, Medium=2, High=3)
    val_labels(mydata$Q6.1_1_2)<-c(Low=1, Medium=2, High=3)
    val_labels(mydata$Q7.1_1_1)<-c(Low=1, Medium=2, High=3)
    val_labels(mydata$Q7.1_1_2)<-c(Low=1, Medium=2, High=3)
mydata
# A tibble: 14 x 4
     Q6.1_1_1   Q6.1_1_2   Q7.1_1_1   Q7.1_1_2
    <dbl+lbl>  <dbl+lbl>  <dbl+lbl>  <dbl+lbl>
 1 2 [Medium] 1 [Low]    1 [Low]    3 [High]  
 2 1 [Low]    3 [High]   2 [Medium] 1 [Low]   
 3 3 [High]   1 [Low]    1 [Low]    3 [High]  
 4 1 [Low]    1 [Low]    2 [Medium] 1 [Low]   
 5 2 [Medium] 1 [Low]    1 [Low]    2 [Medium]
 6 3 [High]   2 [Medium] 3 [High]   1 [Low]   
 7 1 [Low]    3 [High]   3 [High]   3 [High]  
 8 3 [High]   3 [High]   1 [Low]    2 [Medium]
 9 2 [Medium] 1 [Low]    2 [Medium] 3 [High]  
10 1 [Low]    3 [High]   3 [High]   1 [Low]   
11 1 [Low]    1 [Low]    2 [Medium] 3 [High]  
12 1 [Low]    1 [Low]    1 [Low]    1 [Low]   
13 2 [Medium] 1 [Low]    3 [High]   1 [Low]   
14 2 [Medium] 2 [Medium] 2 [Medium] 3 [High] 

从问题字符串中删除项目编号:

varlist<-mydata %>% 
  colnames() %>% 
  as_tibble() %>% 
  separate(value, "qno", sep="_", extra = "drop", fill="right") %>%
  unique() %>% 
  pull()
> varlist
[1] "Q6.1" "Q7.1"

生成子表:

for (v in varlist) {
  assign(paste0("table", v), select(mydata, matches(v)))
} 

这给了我称为 tableQ6.1 和 tableQ7.1 的子表。到目前为止,一切顺利。

但是,当我尝试在生成每个子表时为其添加平均列(给出每行的平均值)时,我找不到告诉 mutate() 使用动态名称的方法桌子。这些是我尝试过的几个选项,但我得到的(包括这些以及更多)都是错误,所以我一定遗漏了一些明显的东西:

for (v in varlist) {
  assign(paste0("table", v), select(mydata, matches(v)))
  tabname<-sym(paste0("table", v))
  mutate({{tabname}}, mean=rowMeans(across(where(is.numeric)), na.rm = FALSE))
}

for (v in varlist) {
  assign(paste0("table", v), select(mydata, matches(v)))
  tabname<-"table{v}" %>%
    mutate("mean{v}":=rowMeans(across(where(is.numeric)), na.rm = FALSE))
}

欢迎任何指导(包括关于这是否是最佳方法的更广泛的 cmets)!

【问题讨论】:

    标签: r dynamic dplyr


    【解决方案1】:

    您可以使用split.default 来拆分具有相似列名的数据框,然后对每个子集进行逐行平均。这将避免您创建中间数据帧和变量。

    sapply(split.default(mydata, sub('\\..*', '', names(mydata))), rowMeans)
    
    #       Q6  Q7
    # [1,] 1.5 2.0
    # [2,] 2.0 1.5
    # [3,] 2.0 2.0
    # [4,] 1.0 1.5
    # [5,] 1.5 1.5
    # [6,] 2.5 2.0
    # [7,] 2.0 3.0
    # [8,] 3.0 1.5
    # [9,] 1.5 2.5
    #[10,] 2.0 2.0
    #[11,] 1.0 2.5
    #[12,] 1.0 1.0
    #[13,] 1.5 2.0
    #[14,] 2.0 2.5
    

    【讨论】:

    • 谢谢。但我认为我需要创建子表以允许在问题级别进行分析、绘制数据等等。
    • @donnek subtables &lt;- split.default(mydata, sub('\\..*', '', names(mydata))) 这是您的子表所在的位置。如果将它们保存在列表中而不是在全局环境中创建对象,则管理起来会更好、更容易。
    • 啊啊,我明白你的意思了。我得到一个列表列表,后者是每个问题的数据框。我可以访问那些subtables$Q6subtables[["Q6"]]subtables %&gt;% pluck("Q6"),但是有没有办法将问题列表(例如c("Q6", "Q7", "Q12") 传递到子表列表并获取这些问题的列?我似乎不能为此获得正确的调用 - 显然要在列表上做很多学习!
    • 您可以通过subtables[c('Q6', 'Q7', 'Q12')] 获取多个列表。
    • 是的,但这只是给出了subtables 的一个子集 - 我试图在一个数据框中获取该子集中的列。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-08
    • 2018-05-06
    • 2020-08-13
    • 2018-09-26
    • 1970-01-01
    • 2018-09-22
    相关资源
    最近更新 更多