【问题标题】:ggplot facet grid within a factor一个因子内的ggplot构面网格
【发布时间】:2020-06-08 21:55:38
【问题描述】:

考虑如下所示的数据

fitem<-rep(rep(1:16,each=3),2)
fsubs<-factor(rep(rep(paste('sub',1:3,sep=''),16),2))
ftime<-factor(as.character(rep(c('a','b'),each=48)))
fcounts<-as.numeric(round(runif(96,1,10)))
fdf<-data.frame(fsubs,fitem,fcounts,ftime)


head(df)

  fsubs fitem fcounts ftime
1  sub1     1       8     a
2  sub2     1      10     a
3  sub3     1       4     a
4  sub1     2       4     a
5  sub2     2       1     a
6  sub3     2       6     a

我想绘制一个分面网格,显示两个时间点('a','b')的计数,以主题为单位。我似乎无法弄清楚如何在 ggplot 中绘制它

这是我的丑陋尝试

fdf_counts<-data.frame()
for (i in unique(fdf$fsubs)){
  fdf_counts<-append(fdf_counts,cbind(fdf%>%filter(fsubs==i,ftime=='a')%>%dplyr::select(fcounts),
                        fdf%>%filter(fsubs==i,ftime=='b')%>%dplyr::select(fcounts)))

fdf_counts<-data.frame(fdf_counts)
}

s1<-ggplot(fdf_counts,aes(x=fcounts,y=fcounts.1))+geom_point()+geom_smooth(method='lm')+labs(x='a',y='b',title='sub1')
s2<-ggplot(fdf_counts,aes(x=fcounts.2,y=fcounts.3))+geom_point()+geom_smooth(method='lm')+labs(x='a',y='b',title='sub2')
s3<-ggplot(fdf_counts,aes(x=fcounts.4,y=fcounts.5))+geom_point()+geom_smooth(method='lm')+labs(x='a',y='b',title='sub3')



plot_grid(s1,s2,s3)#from 'cowplot' package

如何使用原始的fdf data.frame 做到这一点?尤其是随着订阅人数的增加

或者例如,如果我想在所有子系统中绘制一个散点图,其中 fcounts 以 ftime(a) 为 x 轴,ftime(b) 为 y 轴?

【问题讨论】:

  • 两个时间点是什么?
  • 时间点是因素'a','b',如果不清楚,抱歉!

标签: r ggplot2 scatter-plot facet-grid


【解决方案1】:

考虑在 fsubsfitem 上单独使用数据框的 merge 解决方案(每个 fsubsftime 分组)。这种方法允许您保留较长的tidy data 格式,这是ggplot 的理想格式,因为您可以在不重复使用fsubs 的情况下使用facet_grid

mdf <- merge(subset(fdf, ftime=="a"), 
             subset(fdf, ftime=="b"), 
             by=c("fsubs", "fitem"), 
             suffixes=c("", "_"))

ggplot(mdf, aes(x=fcounts, y=fcounts_)) + 
  geom_point() + 
  geom_smooth(method='lm') +
  labs(x='a', y='b') + 
  facet_grid(~fsubs)

【讨论】:

  • 谢谢,这正是我想要的。非常优雅,仍然保持整洁的数据格式。
  • 很高兴听到并乐于提供帮助!编码愉快!
【解决方案2】:

这应该让你接近:

library(dplyr)
library(tidyr)
library(tibble)
library(ggplot2)

fitem<-rep(rep(1:16,each=3),2)
fsubs<-factor(rep(rep(paste('sub',1:3,sep=''),16),2))
ftime<-factor(as.character(rep(c('a','b'),each=48)))
fcounts<-as.numeric(round(runif(96,1,10)))
fdf<-tibble(fsubs,fitem,fcounts,ftime)


fdf <- fdf %>%
  group_by(ftime) %>%
  mutate(row_id = row_number()) %>%
  pivot_wider(values_from = fcounts,
              names_from = ftime)


ggplot(data = fdf, aes(x = a, y = b)) +
  geom_point() +
  geom_smooth(method = "lm") +
  facet_wrap(fsubs ~ ., ncol = 1)

tidyr 函数 pivot_wider 允许我们在没有显式循环的情况下创建所需数据的形状:使用来自 fcounts 的值创建新列 ab。我们确实需要创建一个唯一的行 ID 来完成这项工作。

顺便说一句,当我运行您的代码时,图表看起来与您在问题中发布的不同。

有了这个输出:

【讨论】:

    【解决方案3】:

    刚刚尝试创建一个可以分析所有 4 个变量的可视化。得到了geom_histogram

    ```{r}
    fitem<-rep(rep(1:16,each=3),2)
    fsubs<-factor(rep(rep(paste('sub',1:3,sep=''),16),2))
    ftime<-factor(as.character(rep(c('a','b'),each=48)))
    fcounts<-as.numeric(round(runif(96,1,10)))
    fdf<-data.frame(fsubs,fitem,fcounts,ftime)
    
    fdf_counts<-data.frame()
    for (i in unique(fdf$fsubs)){
      fdf_counts<-append(fdf_counts,cbind(fdf%>%filter(fsubs==i,ftime=='a')%>%dplyr::select(fcounts),
                            fdf%>%filter(fsubs==i,ftime=='b')%>%dplyr::select(fcounts)))
    
    fdf_counts<-data.frame(fdf_counts)
    }
    
    
    ggplot(data = fdf, mapping = aes(x = fdf$fsubs, y = fdf$fcounts, fill = fdf$fitem)) +               geom_bar(stat = "identity", position =     "dodge") + facet_grid(cols = vars(ftime))
    
    
    ```
    

    【讨论】:

      猜你喜欢
      • 2021-08-07
      • 1970-01-01
      • 2019-11-23
      • 2019-02-13
      • 2022-01-08
      • 2019-03-16
      • 2020-12-15
      • 1970-01-01
      相关资源
      最近更新 更多