【问题标题】:In R, plotting wide form data with ggplot2 or base plot. Is there a way to use ggplot2 without melting wide form data frame?在 R 中,使用 ggplot2 或基本图绘制宽格式数据。有没有办法在不熔化宽格式数据框的情况下使用 ggplot2?
【发布时间】:2014-06-07 11:20:34
【问题描述】:

我有一个看起来像这样的数据框(虽然大了数千倍)。

df<-data.frame(sample(1:100,10,replace=F),sample(1:100,10,replace=F),runif(10,0,1),runif(10,0,1),runif(10,0,1), rep(c("none","summer","winter","sping","allyear"),2))
names(df)<-c("Mother","ID","Wavelength1","Wavelength2","Wavelength3","WaterTreatment")
df
   Mother ID Wavelength1 Wavelength2 Wavelength3 WaterTreatment
1       2 34   0.9143670  0.03077356  0.82859497           none
2      24 75   0.6173382  0.05958151  0.66552338         summer
3      62 77   0.2655572  0.63731302  0.30267893         winter
4      30 98   0.9823510  0.45690437  0.40818031          sping
5       4 11   0.7503750  0.93737900  0.24909228        allyear
6      55 76   0.6451885  0.60138475  0.86044856           none
7      97 21   0.5711019  0.99732068  0.04706894         summer
8      87 14   0.7699293  0.81617911  0.18940531         winter
9      92 30   0.5855559  0.70152698  0.73375917          sping
10     93 44   0.1040359  0.85259166  0.37882469        allyear

我想在 y 轴上绘制波长值,在 x 轴上绘制波长值。我有两种方法:

第一种可行的方法,但使用基础图并且需要的代码比必要的多:

colors=c("red","blue","green","orange","yellow")
plot(0,0,xlim=c(1,3),ylim=c(0,1),type="l")
for (i in 1:10) {
  if      (df$WaterTreatment[i]=="none"){
    a<-1
  } else if (df$WaterTreatment[i]=="allyear") {
    a<-2
  }else if (df$WaterTreatment[i]=="summer") {
    a<-3
  }else if (df$WaterTreatment[i]=="winter") {
    a<-4
  }else if (df$WaterTreatment[i]=="spring") {
    a<-5
  }
  lines(seq(1,3,1),df[i,3:5],type="l",col=colors[a])
}

第二种方法:我尝试将数据融合成长格式,然后使用ggplot2。它生成的图不正确,因为每个水处理都有一条线,而不是每个“母亲”“ID”(唯一标识符,原始数据框中的行)都有一条线。

require(reshape2)
require(data.table)
df_m<-melt(df,id.var=c("Mother","ID","WaterTreatment"))
df_m$variable<-as.numeric(df_m$variable)  #sets wavelengths to numeric
qplot(x=df_m$variable,y=df_m$value,data=df_m,color=df_m$WaterTreatment,geom = 'line')

关于 ggplot2,我可能缺少一些简单的东西来修复线条的绘制。我是 ggplot 的新手,但我正在努力熟悉它并希望在此应用程序中使用它。

但更广泛地说,有没有一种有效的方法可以在 ggplot2 中绘制这种类型的宽格式数据?转换/融化数据所需的时间是巨大的,我想知道这是否值得,或者是否有某种解决方法可以消除融化时产生的冗余单元。

感谢您的帮助,如果您需要更清楚地了解这个问题,请告诉我,我可以编辑。

【问题讨论】:

    标签: r ggplot2 melt


    【解决方案1】:

    我想指出,您基本上是在重新发明现有的基本绘图功能,即matplot。这可以取代你的情节和 for 循环:

    matplot(1:3, t( df[ ,3:5] ), type="l",col=colors[ as.numeric(df$WaterTreatment)] )
    

    考虑到这一点,您可能想要搜索 SO:[r] matplot ggplot2,就像我一样,然后 see if this 看看这个或任何其他命中是否有效。

    【讨论】:

    • 谢谢。 matplot 效果很好。其他帖子正在扩大我的理解。我应该删除我的问题,因为问它真的没有意义吗?
    • 我觉得删除太晚了。这确实是有道理的,根据我的搜索,我不清楚是否有一个好的答案,但也许一个 R 半神会从天上掉下来。
    【解决方案2】:

    看起来您需要为每个 ID 单独设置一行,但您希望根据 WaterTreatment 的值对这些行进行着色。如果是这样,您可以在 ggplot 中这样做:

    ggplot(df_m, aes(x=variable, y=value, group=ID, colour=WaterTreatment)) + 
           geom_line() + geom_point()
    

    您还可以使用分面来更轻松地查看不同级别的 WaterTreatment

    ggplot(df_m, aes(x=variable, y=value, group=ID, colour=WaterTreatment)) + 
        geom_line() + geom_point() + 
        facet_grid(WaterTreatment ~ .)
    

    回答您的一般问题:ggplot 设置为使用“长”(即融化)数据框最容易和最强大地工作。我想您可以使用“宽”数据框并为要绘制的每种因素组合绘制单独的图层。但与将数据转换为正确格式的单个 melt 命令相比,这将是很多额外的工作。

    【讨论】:

    • 感谢您对 ggplot 和分组的帮助。
    猜你喜欢
    • 1970-01-01
    • 2019-05-31
    • 2021-02-10
    • 2019-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-08
    • 2023-03-08
    相关资源
    最近更新 更多