从公开问卷中汇总和绘制观察结果

时间:2016-03-05 11:56:44

标签: r dataframe

摘要

我想创建一个像这样的箱形图,显示城市每个街区最常见的问题。 Sample boxplot with real data

不幸的是,盒子图没有用,因为我使用的数据来自一个开放的调查问卷,它有两个主要问题:

  1. 有很多不相关的答案(无关紧要,我指的是只有一个或几个人使用的答案)
  2. 有些问题涉及相同的概念,但已被不同地重新定义,因此被视为不同的东西。
  3. 为了使它更有用,我想在一个组中聚合不相关的答案"例如:other problems并重命名相同的问题,以便它们的措辞准确,从而可以显示在barplot正确。不幸的是,我没有成功。

    详细说明

    让我们看一下示例代码(数据框上的名称只是示例:我为了清晰起见修改了它们,因此更容易理解两个或更多问题是相关的,但是实际的术语不能总是从正则表达式中推导出来:

    library(plyr)
    library(dplyr)
    library(tidyr)
    
    df= read.csv("http://pastebin.com/raw/bUxANQw6")
    
    problems = df %>%
      select(Problems) %>%
      gather(variable, value) %>%
      group_by(value) %>%
      summarise(Total = n()) %>%
      arrange(desc(Total))
    

    以下数据框的结果如下:

    > problems
    Source: local data frame [27 x 2]
    
              value Total
    1     Problem 1   282
    2     Problem 3   268
    3     Problem 2   186
    4   No problems   160
    5     Problem 4    76
    6     Problem 5    68
    7     Problem 6     6
    8     Problem 7     5
    9  Doesn't know     4
    10    Problem 8     2
    ..          ...   ...
    > 
    

    可以看出,我们有27个问题,更仔细地看待它们,我们可以建立一些群体:

    1. 相关数据:问题1到7 + No ProblemsDoesn't know
    2. Synomyms:我们有Problem 9Problem 9'Problem 9''Problem 9'''(以及其他)
    3. 不相关的数据,应该在一个标签下分组,例如"其他问题":问题12到18
    4. 我建议的方法

      我认为我能做的就是克服这两个问题:

      为了处理同义词,我想到将同义词值重命名为单个值,可能使用revalue命令,如下所示:

      df$Problems = revalue(df$Problems, c('Problem 9’' = 'Problem 9',
                                           'Problem 9’’' = 'Problem 9',
                                           'Problem 9’’’' = 'Problem 9'))
      

      然而,作为一个R新手(以及编程语言的新手),我认为应该有更快的方法来实现这一点,因为维护一个同义词'字典"将会非常繁琐,并会在获得更多回复时增长。

      为了处理无关的答案,我可以采取类似的方法,并将其重新评估为Other problems,但我想以自动方式进行,因为列表由于调查问卷尚未完成,因此不相关的条款将会增加,我无法手动映射所有这些条款(例如:映射已由少于5人投票的所有值Total < 5)。我想我应该创建一个函数并使用一个控制结构(for ... in),但我还没有成功。

      由于我需要显示按邻域分组的答案的箱线图,我担心我无法原样使用problems数据帧。因此,尽管计算每个问题的总投票数是有用的,但除了将其用作信息数据之外,我不知道如何处理它。另一方面,我无法仅根据每个社区收到的回复来确定答案是否无关,因为它会使结果产生偏差,因为预计不同的社区可能会有不同的问题。

      对这两个问题的任何帮助都将非常感激。感谢

1 个答案:

答案 0 :(得分:2)

我查看了您的数据和代码。您的数据框problems获得了Problem 9’Problem 7'等等。所以你想要的是删除'。那是你的任务之一。您可以使用以下行完成此任务。

problems$value <- gsub(pattern = "’+|'+", replacement = "", x = problems$value)

您可以使用which()完成其他任务。您想要查找Total < 5行。使用which(),您可以找到索引。然后,使用value替换行中Other problems中的内容。我希望这就是你所追求的。

problems$value[which(problems$Total < 5)] <- "Other problems"

数据

problems <- structure(list(value = c("Problem 1", "Problem 3", "Problem 2", 
"No problems", "Problem 4", "Problem 5", "Problem 6", "Problem 7", 
"Doesn't know", "Problem 8", "Problem 9", "Problem 9’", "Other problems", 
"Problem 10", "Problem 10’", "Problem 11", "Problem 11'", "Problem 12", 
"Problem 13", "Problem 14", "Problem 15", "Problem 16", "Problem 17", 
"Problem 18", "Problem 7'", "Problem 9’’", "Problem 9’’’"
), Total = c(282L, 268L, 186L, 160L, 76L, 68L, 6L, 5L, 4L, 2L, 
2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-27L), .Names = c("value", "Total"))

修改

看到OP的第一条评论,以下几行将构成一个数据框来绘制图形。

count(df, Neighborhoods, Problems) -> temp

temp$Problems <- gsub(pattern = "’+|'+", replacement = "", x = temp$Problems)

temp$Problems[which(temp$n < 5)] <- "Other problems"

group_by(temp, Neighborhoods, Problems) %>%
summarize(Total = sum(n)) -> temp2