in R, how to automatically plots based on lists?

别说谁变了你拦得住时间么 提交于 2019-12-18 07:16:10

问题


I've got a survey results for two products categories, here is the data

surveyresults<-data.frame("Name"=c("Adam","John"),
"Gender"=c("m","m"),
"City"=c("Sydney","Melbourne"),
"Product"=c("Fashion","Electronics"),
"fash_pay_cash"=c(5,"NA"),
"fash_pay_card"=c(5,"NA"),
"elc_pay_cash"=c("NA",5),
"elc_pay_card"=c("NA",6),
"fash_DlvTime_morning"=c(5,"NA"),
"fash_DlvTime_afternoon"=c(7,"NA"),
"elc_DlvTime_morning"=c("NA",5),
"elc_DlvTime_afternoon"=c("NA",8))
surveyresults

and i need to plot each element in this list

fshnprxlist<-list("fash_pay","fash_DlvTime")

which represents the prefix of each column needed to be ploted and should be the plot title name

since I'm the survey creator, so i built it based on this lists

list1<-list("fashion","electronics")
listPM<-list("cash","card")
listDT<-list("morning","afternoon")
fshlistPM<-paste("fash_pay",listPM,sep="_")
fshlistDT<-paste("fash_DlvTime",listDT,sep="_")
elcprxlist<-list("elc_pay","elc_DlvTime")
elclistPM<-paste("elc_pay",listPM,sep="_")
elclistDT<-paste("elc_DlvTime",listDT,sep="_")

my request is simply, dynamically create plot for each element of the 1st list using the column that starts with the "text of each element in the first elements


回答1:


Here, we could reshape into 'long' format and then use ggplot to plot

library(dplyr)
library(tidyr)
library(ggplot2)
library(plotly)
p1 <- surveyresults %>%
      type.convert(as.is = TRUE) %>%
      pivot_longer(cols = fash_pay_cash:elc_DlvTime_afternoon, 
        names_to = c("group", ".value"), names_pattern = "^(\\w+_\\w+)_(\\w+)$") %>% 
      pivot_longer(cols = cash:afternoon, values_drop_na = TRUE) %>% 
      group_by(group, name) %>%
      summarise(value = sum(value)) %>%
      ggplot(aes(x = name, y = value, fill = group)) + 
        geom_col(position = 'dodge') +
        facet_wrap(vars(group))

ggplotly(p1)

-output


Or we can use facet_wrap_paginate from ggforce

library(ggforce)
p1 <- surveyresults %>%
       type.convert(as.is = TRUE) %>%
       pivot_longer(cols = fash_pay_cash:elc_DlvTime_afternoon, 
         names_to = c("group", ".value"),
               names_pattern = "^(\\w+_\\w+)_(\\w+)$") %>% 
       pivot_longer(cols = cash:afternoon, values_drop_na = TRUE) %>% 
       group_by(group, name) %>%
       summarise(value = sum(value)) %>%
       ggplot(aes(x = name, y = value, fill = group)) + 
         geom_col(position = 'dodge') +
         facet_wrap_paginate(~ group, ncol = 1, nrow = 2, page = 2)

n <- n_pages(p1)
pdf('surveyout.pdf')
for(i in seq_len(n)) print(p1 + 
           facet_wrap_paginate(~ group, ncol = 1, nrow = 2, page = i))
dev.off()

Or it can be split into smaller subsets, create ggplot in each and then apply the plotly on it separately

library(purrr)
lstOut <- surveyresults %>%
           type.convert(as.is = TRUE) %>%
           pivot_longer(cols = fash_pay_cash:elc_DlvTime_afternoon, 
              names_to = c("group", ".value"),
                names_pattern = "^(\\w+_\\w+)_(\\w+)$") %>% 
           pivot_longer(cols = cash:afternoon, values_drop_na = TRUE) %>% 
           group_by(group, name) %>%
           summarise(value = sum(value)) %>%
           ungroup %>%
           group_split(grp =(as.integer(factor(group, 
               levels = unique(group)))%/% 3) + 1) %>%
           map(~ 
             ggplot(.x, aes(x = name, y = value, fill = group)) + 
             geom_col(position = 'dodge') +
             facet_wrap(vars(group)) -> p)

ggplotly(lstOut[[1]])
ggplotly(lstOut[[2]])


来源:https://stackoverflow.com/questions/59344173/in-r-how-to-automatically-plots-based-on-lists

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!