52

我有一个调查文件,其中行是观察和列问题。

以下是它们看起来像的一些假数据:

People,Food,Music,People
P1,Very Bad,Bad,Good
P2,Good,Good,Very Bad
P3,Good,Bad,Good
P4,Good,Very Bad,Very Good
P5,Bad,Good,Very Good
P6,Bad,Good,Very Good

我的目标是用ggplot2.

  • 我绝对不在乎颜色,设计等。
  • 该图与假数据不对应

在此处输入图像描述

这是我的假数据:

raw <- read.csv("http://pastebin.com/raw.php?i=L8cEKcxS",sep=",")
raw[,2]<-factor(raw[,2],levels=c("Very Bad","Bad","Good","Very Good"),ordered=FALSE)
raw[,3]<-factor(raw[,3],levels=c("Very Bad","Bad","Good","Very Good"),ordered=FALSE)
raw[,4]<-factor(raw[,4],levels=c("Very Bad","Bad","Good","Very Good"),ordered=FALSE)

但是,如果我选择 Y 作为计数,那么我将面临选择 X 和 Group 值的问题......我不知道不使用是否能成功reshape2......我也厌倦了使用带有融化功能的 reshape . 但是不明白怎么用。。。

4

2 回答 2

103

编辑:八年后...

这需要一个 tidyverse 解决方案,所以这里有一个,所有非基础包都明确说明,以便您知道每个函数来自哪里(除了read.csv哪个utils来自 base R):

library(magrittr) # needed for %>% if dplyr is not attached

"http://pastebin.com/raw.php?i=L8cEKcxS" %>%
  read.csv(sep = ",") %>%
  tidyr::pivot_longer(cols = c(Food, Music, People.1),
                      names_to = "variable",
                      values_to = "value") %>%
  dplyr::group_by(variable, value) %>%
  dplyr::summarise(n = dplyr::n()) %>%
  dplyr::mutate(value = factor(
    value,
    levels = c("Very Bad", "Bad", "Good", "Very Good"))
  ) %>%
  ggplot2::ggplot(ggplot2::aes(variable, n)) +
  ggplot2::geom_bar(ggplot2::aes(fill = value),
                    position = "dodge",
                    stat = "identity")

原答案:

首先,您需要获取每个类别的计数,即每个组(食物、音乐、人)有多少坏和商品等。这将像这样完成:

raw <- read.csv("http://pastebin.com/raw.php?i=L8cEKcxS",sep=",")
raw[,2]<-factor(raw[,2],levels=c("Very Bad","Bad","Good","Very Good"),ordered=FALSE)
raw[,3]<-factor(raw[,3],levels=c("Very Bad","Bad","Good","Very Good"),ordered=FALSE)
raw[,4]<-factor(raw[,4],levels=c("Very Bad","Bad","Good","Very Good"),ordered=FALSE)

raw=raw[,c(2,3,4)] # getting rid of the "people" variable as I see no use for it

freq=table(col(raw), as.matrix(raw)) # get the counts of each factor level

然后您需要从中创建一个数据框,将其融化并绘制出来:

Names=c("Food","Music","People")     # create list of names
data=data.frame(cbind(freq),Names)   # combine them into a data frame
data=data[,c(5,3,1,2,4)]             # sort columns

# melt the data frame for plotting
data.m <- melt(data, id.vars='Names')

# plot everything
ggplot(data.m, aes(Names, value)) +   
  geom_bar(aes(fill = variable), position = "dodge", stat="identity")

这就是你所追求的吗?

在此处输入图像描述

为了澄清一点,在ggplot 多个分组栏中,您有一个如下所示的数据框:

> head(df)
  ID Type Annee X1PCE X2PCE X3PCE X4PCE X5PCE X6PCE
1  1    A  1980   450   338   154    36    13     9
2  2    A  2000   288   407   212    54    16    23
3  3    A  2020   196   434   246    68    19    36
4  4    B  1980   111   326   441    90    21    11
5  5    B  2000    63   298   443   133    42    21
6  6    B  2020    36   257   462   162    55    30

由于您在第 4-9 列中有数值,这些数值稍后将绘制在 y 轴上,因此可以轻松地对其进行转换reshape和绘制。

对于我们当前的数据集,我们需要类似的东西,所以我们曾经freq=table(col(raw), as.matrix(raw))得到这个:

> data
   Names Very.Bad Bad Good Very.Good
1   Food        7   6    5         2
2  Music        5   5    7         3
3 People        6   3    7         4

想象一下你有Very.Bad, Bad,Good等等而不是X1PCE, X2PCE, X3PCE。看到相似之处了吗?但我们需要先创建这样的结构。因此freq=table(col(raw), as.matrix(raw)).

于 2013-08-10T13:24:04.547 回答
0

在@jakub 的回答中,计算是在数据传递到之前完成的ggplot(),这就是为什么将statingeom_bar设置为"identity"(即按原样获取数据并且不对其执行任何操作)。

另一种方法是让ggplot您为您计数,因此我们可以使用stat = "count",默认值geom_bar

library(ggplot2)
ggplot(stack(df1[, -1]), aes(ind, fill = values)) +
         geom_bar(position = "dodge")

在此处输入图像描述

数据

df1 <- read.csv(text = "People,Food,Music,People
P1,Very Bad,Bad,Good
P2,Good,Good,Very Bad
P3,Good,Bad,Good
P4,Good,Very Bad,Very Good
P5,Bad,Good,Very Good
P6,Bad,Good,Very Good
P7,Bad,Very Bad,Good
P8,Very Good,Very Bad,Good
P9,Very Bad,Good,Bad
P10,Bad,Good,Very Bad
P11,Good,Bad,Very Bad
P12,Very Bad,Bad,Very Good
P13,Bad,Very Good,Bad
P14,Bad,Very Good,Very Bad
P15,Good,Good,Good
P16,Very Bad,Very Good,Very Bad
P17,Very Bad,Good,Good
P18,Very Bad,Very Bad,Bad
P19,Very Good,Very Bad,Very Bad
P20,Very Bad,Bad,Good", header = TRUE)
于 2022-02-12T09:09:19.437 回答