【问题标题】:Long form using colnames使用列名的长格式
【发布时间】:2018-10-28 00:21:44
【问题描述】:

假设我有以下数据

 A <- c(4,4,4,4,4)
 B <- c(1,2,3,4,4)
 C <- c(1,2,4,4,4)
 D <- c(3,2,4,1,4)
 E <- c(4,4,4,4,5)

data <- data.frame(A,B,C,D,E)
data<- t(data)
colnames(data) = c("num1","freq1","freq2","freq3","totfreq")

> data
  num1 freq1 freq2 freq3 totfreq
A    4     4     4     4       4
B    1     2     3     4       4
C    1     2     4     4       4
D    3     2     4     1       4
E    4     4     4     4       5

我正在尝试绘制分组条形图。两者上的 x 轴应该是我的变量 A:Ey 是每个字母的 freq1freq2freq3 的值。我还需要保持按totfreq 中的值绘制变量A:E 的能力。

我知道我需要转换为长格式,但我在设置数据时遇到了问题。不知何故,我需要ABCDE 需要堆叠成一列,另一列堆叠成freq1freq2freq3totfreq 和然后是最后一列的值。任何建议如何做到这一点?

我希望最好在 plotly 中绘图,但 ggplot 也可以工作

【问题讨论】:

  • 所以您希望条形的高度是 freq1、freq2、freq3 和 totfreq 的总和? “那么最后一列的值”是指哪些值?
  • 另外,这似乎是一个关于如何在准备中重塑数据的问题,而不是关于如何绘制它的问题。我建议删除ggplot2plotly 标签,因为这两个标签都不需要回答这个问题。相反,一旦数据成形,他们会考虑构建绘图的可能后续问题
  • 条的高度应该是频率变量列中的每个值。所以 A 将有 3 个条形表示 freq1、freq2、freq3 中的值。但是我需要设置它,所以我可以选择只获取 totfreq,所以在不同的图表中,我可以绘制 A 只有 1 个 bar 的位置,以获取 totfreq 中的值

标签: r tidyr melt


【解决方案1】:

首先,您必须格式化数据以便对其进行处理,然后让 ggplot2 发挥作用。

找到下面的代码和输出图:

library(dplyr)         #To use mutate
library(ggplot2)
library(reshape2)      #To use melt
library(plotly)
A <- c(4,4,4,4,4)
B <- c(1,2,3,4,4)
C <- c(1,2,4,4,4)
D <- c(3,2,4,1,4)
E <- c(4,4,4,4,5)

data <- data.frame(A,B,C,D,E)
data2=names(data)
data<- t(data)
colnames(data) = c("num1","freq1","freq2","freq3","totfreq")

data=data.frame(data)                      
#Because mutate only works for data.frame not matrix

data=mutate(data,names=data2)%>%select("freq1","freq2","freq3","freq3","totfreq","names")  
# Adding names and removing num1

meltdata=melt(data,id.vars="names")        
#Because we need melted data to perform 

#Graph 1 (colourless and boring)
Graph1=ggplot(meltdata,aes(x=names,y=value))+geom_col()+facet_wrap(~variable)
#Graph 2 (Cool one)
Graph2=ggplot(meltdata,aes(x=names,y=value,fill=variable))+geom_col()+geom_text(label=meltdata$value,position="stack")

#Graph 3 is the best I guess
meltdata=mutate(meltdata,xval=1)
Graph3=ggplot(meltdata,aes(x=xval,y=value,fill=variable))+geom_col()+geom_text(label=meltdata$value,position = position_stack(vjust = 0.5))+
  facet_grid(~names)+theme(panel.background = element_blank(),axis.text.x = element_blank(),
                           axis.ticks.x = element_blank())
Graph3
#If you like plotly so much then just use it by passing ggplot variable, But ggplot is better if you ask me
ggplotly(Graph1)
ggplotly(Graph2)
ggplotly(Graph3)

【讨论】:

    【解决方案2】:

    首先,您有一个矩阵,但可能需要一个数据框。将其设置为 tibble 将删除行名,这是您存储字母的位置,所以

    as.data.frame(data) %>% rownames_to_column("id")
    

    将为您提供一个包含id 列字母的数据框。

    您希望通过收集所有 freq 列来将此数据转换为长格式。然后,我添加一个给出观察类型的列;这不是必需的,但既然您说您想轻松过滤两种类型之一——freq1 等组或totfreq——这是我经常使用的方便设置。

    library(tidyverse)
    
    A <- c(4,4,4,4,4)
    B <- c(1,2,3,4,4)
    C <- c(1,2,4,4,4)
    D <- c(3,2,4,1,4)
    E <- c(4,4,4,4,5)
    
    data <- data.frame(A,B,C,D,E)
    data<- t(data)
    colnames(data) = c("num1","freq1","freq2","freq3","totfreq")
    
    data_long <- as.data.frame(data) %>%
      rownames_to_column("id") %>%
      gather(key = var, value = value, freq1:totfreq) %>%
      mutate(type = ifelse(var == "totfreq", "total", "by_group"))
    
    head(data_long)
    #>   id num1   var value     type
    #> 1  A    4 freq1     4 by_group
    #> 2  B    1 freq1     2 by_group
    #> 3  C    1 freq1     2 by_group
    #> 4  D    3 freq1     2 by_group
    #> 5  E    4 freq1     4 by_group
    #> 6  A    4 freq2     4 by_group
    

    使用type 列,按类型过滤以进行绘图非常容易。这可以让您将过滤后的数据框通过管道传输到 ggplot 之类的内容中,或者为您提供一个用于分面或映射到美学的列。

    # for grouped bar chart
    data_long %>% filter(type == "by_group")
    #>    id num1   var value     type
    #> 1   A    4 freq1     4 by_group
    #> 2   B    1 freq1     2 by_group
    #> 3   C    1 freq1     2 by_group
    #> 4   D    3 freq1     2 by_group
    #> 5   E    4 freq1     4 by_group
    #> 6   A    4 freq2     4 by_group
    #> 7   B    1 freq2     3 by_group
    #> 8   C    1 freq2     4 by_group
    #> 9   D    3 freq2     4 by_group
    #> 10  E    4 freq2     4 by_group
    #> 11  A    4 freq3     4 by_group
    #> 12  B    1 freq3     4 by_group
    #> 13  C    1 freq3     4 by_group
    #> 14  D    3 freq3     1 by_group
    #> 15  E    4 freq3     4 by_group
    
    # for total freqs
    data_long %>% filter(type == "total")
    #>   id num1     var value  type
    #> 1  A    4 totfreq     4 total
    #> 2  B    1 totfreq     4 total
    #> 3  C    1 totfreq     4 total
    #> 4  D    3 totfreq     4 total
    #> 5  E    4 totfreq     5 total
    

    reprex package (v0.2.0) 于 2018 年 5 月 17 日创建。

    【讨论】:

    • 天哪,这太完美了。谢谢!你摇滚。 @卡米尔
    猜你喜欢
    • 2019-05-31
    • 1970-01-01
    • 1970-01-01
    • 2019-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-04
    相关资源
    最近更新 更多