【问题标题】:R: Output columns as textR:将列输出为文本
【发布时间】:2021-09-04 20:10:44
【问题描述】:

背景:我在 SPSS .sav 文件中有调查结果。一些调查问题是开放的,受访者可以输入自己的答案。在 SPSS 中,我可以只选择一个或多个列,响应将作为文本文件输出,响应按每个问题(列内容)分组,每个响应用空行分隔。然后,可以通过为文本中的短语或句子分配代码,将此文本文件用于主题分析。

我似乎找不到在 R 中做同样事情的简单方法。所有常用的导出格式都以表格形式输出。在 RStudio 中选择列会给出文本输出,其中每个响应都按受访者而不是按列分组。

玩具示例:

library(labelled)
library(tidyverse)

comments<-tibble(
  shakey=as.character(c("To be or not to be", "", "Alas poor Yorick", "", "Is this a dagger that I see before me?", "A rose by any other name")), 
  versey=as.character(c("", "The boy stood on the burning deck", "", "Oft in the stilly night", "", "Lars Porsena of Clusium, by the nine gods he swore"))
  )

var_label(comments$shakey)<-"Can you quote some Shakespeare?"
var_label(comments$versey)<-"Can you quote some poetry?"

我想要的输出是:

*Can you quote some Shakespeare?*

To be or not to be

Alas poor Yorick

Is this a dagger that I see before me?

A rose by any other name

*Can you quote some poetry?*

The boy stood on the burning deck

Oft in the stilly night

Lars Porsena of Clusium, by the nine gods he swore

以列标签为标题,每一列的非空白响应依次列出,以空行分隔。

到目前为止我最接近的是:

comlong<-pivot_longer(comments, everything(),
                     names_to="question",
                     values_to="response") %>%
  arrange(question) %>% 
  filter(response!="")

但是,虽然这会在一列中获得所有响应,但需要进行一些编辑才能将其转换为上述所需格式,这对于更广泛的数据而言并非易事。

最终结果:

我认为,Akrun 的附加 summarise 行是最优雅的。调整后的输出与 SPSS 非常相似:

comments %>%
  summarise(across(everything(), ~ c(paste0(sprintf('**%s**', cur_column()), "\n\n", sprintf('*%s*', var_label(.))), .))) %>%
  pivot_longer(cols = everything(), 
               names_to = 'question', 
               values_to = 'response') %>% 
  arrange(question) %>% 
  filter(response != '') %>% 
  select(response) %>% 
  write.table("comments.md",quote=FALSE, eol="\n\n", row.names=FALSE, col.names=FALSE)

这会插入列名和标签(因为我发现有时标签描述性不够),并将其输出为降价文件,可以在(例如)Qualcoder 中提取该文件以进行主题编码。运行:

pandoc comments.md -o comments.odt

如果您需要,也会生成文字处理器输出。

【问题讨论】:

  • 只是想了解你为什么想要这种糟糕的格式,即为什么你需要这种格式的主题分析?如果您希望文本显示在彼此下方,则 pivot_longer 似乎是一个不错的方法,然后您可以用“问题”列中的列标签替换列名,并在新列中对响应进行编码。
  • 这是 Qualcoder、Nvivo、Atlas.TI 等定性分析工具的标准输入,您希望关注每个人对一个主题的看法,而不是每个人对所有主题的看法.在新列中编码(标记主题)是行不通的,因为通常一条评论会涉及多个主题,而您希望将它们分开以供以后分析。
  • 这适用于“真正的”定性分析,例如当你有来自焦点小组的成绩单或你想要编码的深入采访时,例如MaxQDA 或 Qualcoder 等使用这些工具时,您通常还需要考虑某些主题的空间/长度、位置、重叠(例如,如果在同一个句子中提到人 A 和人 B)。分析来自调查的开放文本回复通常意味着您只想对主题的出现进行编码,而不考虑其他定性特征。因此,您可能会有一个包含主题的“密码本”,每个主题都有一个数字代码......
  • ...然后您只想知道主题 A 和/或主题 B、C、D 等是否发生。在最简单的形式中,这只需要在您分配这些代码的文本列的右侧有尽可能多的列。通常,您会将其转换为二分格式,其中您拥有与主题一样多的编码列,如果出现相应主题,则分配 1,否则分配 0(这允许多重编码)。这可以很容易地分析。这就是为什么我要问您需要哪种确切格式。您可以在 R 或 Excel 或 Caplena(非免费)等工具或其他此类工具中执行此操作。
  • 但是开发码本可能是一个探索过程。并且“代码列”可能是随意组织的。在文本文件中选择一段文本比滚动 x 列以找到正确的列更容易。理想情况下,查看代码的上下文应该允许您查看所有 cmets,而这在电子表格格式中是很困难的。有时让 R 做“显而易见”的事情并不明显。所以是的,我同意您可以使用您提到的工具,但使用专为该任务设计的工具可能更快。

标签: r text output


【解决方案1】:

我们可以先使用summariseacross 来提取var_label 并通过连接追加,然后使用pivot_longer

library(labelled)
library(dplyr)
library(tidyr)
comments %>% 
    summarise(across(everything(), ~ c(var_label(.), .))) %>% 
    pivot_longer(cols = everything(), names_to = 'question', 
        values_to = 'response') %>% 
    arrange(question) %>% 
    filter(response != '')

-输出

# A tibble: 9 x 2
  question response                                          
  <chr>    <chr>                                             
1 shakey   Can you quote some Shakespeare?                   
2 shakey   To be or not to be                                
3 shakey   Alas poor Yorick                                  
4 shakey   Is this a dagger that I see before me?            
5 shakey   A rose by any other name                          
6 versey   Can you quote some poetry?                        
7 versey   The boy stood on the burning deck                 
8 versey   Oft in the stilly night                           
9 versey   Lars Porsena of Clusium, by the nine gods he swore

或者如果我们首先重塑,也有一个选项,即按“问题”进行分组并将“问题”的第一个值作为子集,以从原始数据中提取 var_label 并连接

pivot_longer(comments, everything(),
                     names_to="question",
                     values_to="response") %>%
  arrange(question) %>% 
  filter(response!="") %>% 
  group_by(question) %>% 
  summarise(response = c(var_label(comments[[first(question)]]), 
     response), .groups = 'drop')

-输出

# A tibble: 9 x 2
  question response                                          
  <chr>    <chr>                                             
1 shakey   Can you quote some Shakespeare?                   
2 shakey   To be or not to be                                
3 shakey   Alas poor Yorick                                  
4 shakey   Is this a dagger that I see before me?            
5 shakey   A rose by any other name                          
6 versey   Can you quote some poetry?                        
7 versey   The boy stood on the burning deck                 
8 versey   Oft in the stilly night                           
9 versey   Lars Porsena of Clusium, by the nine gods he swore

【讨论】:

  • 看来你在这里很孤单。 :-)
【解决方案2】:

这是lapply 的输出 -

lapply(comments, function(x) {
  y <- x[x != '']
  values <- paste0(sprintf('*%s*', attr(x, 'label')), "\n\n", 
            paste0(y, collapse = '\n\n'))
  cat(paste0(values, '\n\n'), file = 'output.txt', append = TRUE)
})

【讨论】:

    猜你喜欢
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 2014-01-12
    相关资源
    最近更新 更多