将 R for 循环的结果存储到对象中并使用应用函数绘制图形的问题

威廉

问题是将 for 循环中的图形存储为 R 中的向量。

我编写了一个函数,可以逐表绘制图表(见下文)。

# packages used
library(xlsx)
library(ggplot2)
library(tidyverse)
library(readxl)
library(ggplot2)
library(reshape2)

d1 <- data.frame(options = c("Strongly Agree", "Agree", "Disagree", "N/A",NA), foo2016 =
                   c(1, 4, 5, 6, NA), foo2017 = c(10, 7, 8, 9, NA), foo2018 = c(10, 7, 15, 14, NA))
d2 <- data.frame(options = c("options","Strongly Agree", "Agree", "Disagree", "N/A",NA),
                 foo2016 = c(11, 4, 3, 2, 1, NA), foo2017 = c(12, 6, 5, 4, 5, NA), foo2018 = c(10, 7, 6, 15, 14, NA))

mytables_in_a_list <- list(d1, d2)


x <- mytables_in_a_list

# where x = my tables in a list, n = table index in the list 
foo_graph <- function(x, n){
  tbl1 <- x[[n]]

  if(tbl1[1,1] != "Strongly Agree"){
    tbl1 <- tbl1[-1,]
  }

  #rename column
  names(tbl1) <- c("Options", "2016", "2017", "2018")

  # remove rofoo with NAs
  tbl1 <- tbl1 %>% drop_na()

  cols.num <- c("2016","2017", "2018")

  tbl1[cols.num] <- sapply(tbl1[cols.num],as.numeric)

  sapply(tbl1, class)

  # alternative to removing rofoo with NAs
  # na.omit(tbl)
  mdf <- melt(tbl1, value.name="value", variable.name="year", id.vars="Options")

  foo_graph <- ggplot(data=mdf, aes(x=year, y=value, group = Options, colour = Options)) +
    geom_line() +
    geom_point( size=4, shape=21, fill="white")

foo_graph
}

上面的代码工作正常。但是,由于我有很多表(大约 40 个),我想我可以通过使用for循环来迭代绘图来节省大量时间,以便图形(大约 40 个)可以存储在单个 R 对象中. 我试过for循环(见下面的代码),但我得到的 R 对象是空的,没有错误消息。

# packages used
library(xlsx)
library(ggplot2)
library(tidyverse)
library(readxl)
library(ggplot2)
library(reshape2)

x <- mytables_in_a_list
foo_graph <- list()
for (i in length(x)){
tbl1 <- x[[i]]

# delete table 1st row if the 1st element in the 1st row is not "Strongly Agree" 
if(tbl1[1,1] != "Strongly Agree"){
  tbl1 <- tbl1[-1,]
}

#rename column
names(tbl1) <- c("Options", "2016", "2017", "2018")

# remove rows with NAs
tbl1 <- tbl1 %>% drop_na()

# change "2016","2017", "2018" columns to numeric
cols.num <- c("2016","2017", "2018")
tbl1[cols.num] <- sapply(tbl1[cols.num],as.numeric)

# melt the table
mdf <- melt(tbl1, value.name="value", variable.name="year", id.vars="Options")

# plot the graph with ggplot
foo_graph[[i]] <- ggplot(data=mdf, aes(x=year, y=value, group = Options, colour = Options)) +
  geom_line() +
  geom_point( size=4, shape=21, fill="white")
}

foo_graph

我也知道可以使用 lapply 函数来做同样的事情。我试过 mapply 因为我的函数有两个参数,但不幸的是,我收到了下面的错误。

> mapply(x, foo_graph, n)
Error in get(as.character(FUN), mode = "function", envir = envir) : 
  object 'alistoftables' of mode 'function' was not found

我希望输出是存储在 R 对象中的图形,这样如果我查询对象中的第三个元素,例如foo_graph[3],将显示对象中的第三个图形。但是,下面显示的不是预期的结果。

> foo_graph[3]
[[1]]
NULL

泰奥菲勒斯

没有您的数据,我们无法重现该行为。但这里有一些示例代码可以做到这一点。我使用purrr::map代替循环或apply家庭,但您可以替换maplapply并获得相同的结果。

library(tidyverse)
library(cowplot) # to plot a list of plots

# create some fake data
# make a vector for table size
sz <- 21:60

# function to make data frames
make_tbl <- function(size) {
  a <- sample(x = 1:50, size = size, replace = TRUE)
  b <- sample(x = LETTERS[1:3], size = size, replace = TRUE)
  return(tibble(a,b))
}

# a list of tables
list_of_tbls <- map(sz, make_tbl )

# function to plot
make_plot <- function(tbl) {
  ggplot(data=tbl) + geom_boxplot(aes(x=b, y=a, fill=b))
}

# make plot for all tables
list_of_plots <- map(list_of_tbls, make_plot)

# plot (all 40 if on a big screen)
cowplot::plot_grid(plotlist = list_of_plots[1:8], nrow=2)

在此处输入图片说明

另一种方法是按行绑定表并使用分面绘图。当然,这些表应该具有相同的列。这里的参数.id将创建一个tbl跟踪表的列,因此按 40 个表进行分面很简单。

# alternative to bind the tables if they have the same columns
bound_tbls <- bind_rows(list_of_tbls, .id = "tbl")

# then plot with facet
ggplot(bound_tbls) + geom_boxplot(aes(x=b, y=a, fill=b)) + facet_wrap("tbl", ncol=8)

在此处输入图片说明

编辑:使用 OP 的代码和数据稍微修改绘图功能以匹配虚拟数据。注意最后的使用cowplot::plot_grid但是,如果您只运行all_graphs[[graph_number]].

# library(xlsx)
library(ggplot2)
library(tidyverse)
library(readxl)
library(ggplot2)
library(reshape2)

d1 <-
  data.frame(
    options = c("Strongly Agree", "Agree", "Disagree", "N/A", NA),
    foo2016 =
      c(1, 4, 5, 6, NA),
    foo2017 = c(10, 7, 8, 9, NA)
  )
d2 <-
  data.frame(
    options = c("options", "Strongly Agree", "Agree", "Disagree", "N/A", NA),
    foo2016 = c(11, 4, 3, 2, 1, NA),
    foo2017 = c(12, 6, 5, 4, 5, NA)
  )

mytables_in_a_list <- list(d1, d2)

# where x = my tables in a list, n = table index in the list
foo_graph <- function(x, n) {
  tbl1 <- x[[n]]

  if (tbl1[1, 1] != "Strongly Agree") {
    tbl1 <- tbl1[-1, ]
  }

  #rename column
  # edited to match input data that doesn't have 2018
  names(tbl1) <- c("Options", "2016", "2017")

  # remove rofoo with NAs
  tbl1 <- tbl1 %>% drop_na()

  # edited to match input data that doesn't have 2018
  cols.num <- c("2016", "2017")

  tbl1[cols.num] <- sapply(tbl1[cols.num], as.numeric)

  sapply(tbl1, class)

  # alternative to removing rofoo with NAs
  # na.omit(tbl)
  mdf <-
    melt(
      tbl1,
      value.name = "value",
      variable.name = "year",
      id.vars = "Options"
    )

  foo_graph <-
    ggplot(data = mdf, aes(
      x = year,
      y = value,
      group = Options,
      colour = Options
    )) +
    geom_line() +
    geom_point(size = 4,
               shape = 21,
               fill = "white")

  foo_graph
}

all_graphs <-
  lapply(1:length(x), function(i)
    foo_graph(x = mytables_in_a_list, n = i))

# plot all of them
library(cowplot)
pp <- plot_grid(plotlist = all_graphs,
          align = "hv",
          axis = "ltbr")

# to save:
# ggsave(pp, filename = "all_plots.pdf", width=10, height=5)

要查看绘制在一起的图,只需调用pp对象:

pp

在此处输入图片说明

拥有 之后all_graphs,您应该能够通过调用来查看各个图:

all_graphs[[1]]

在此处输入图片说明

如果您只是调用,all_graphs您将只能在显示窗口中看到最后一个图,因为每个图都被显示并替换为以下内容。在 Rstudio 中,您可以在显示窗格中向后浏览以查看列表中的先前绘图。

> all_graphs
[[1]]

[[2]]

**编辑 2:使用刻面代替cowplot. 对于 40 个表,这应该会更好。不过,问题是是否有办法从 40 个表中的每一个中总结/提取有趣的信息并制作一个汇总图。而不是绘制 40 次调查的原始结果。

library(tidyverse)

d1 <-
  data.frame(
    options = c("Strongly Agree", "Agree", "Disagree", "N/A", NA),
    foo2016 =
      c(1, 4, 5, 6, NA),
    foo2017 = c(10, 7, 8, 9, NA)
  )
d2 <-
  data.frame(
    options = c("options", "Strongly Agree", "Agree", "Disagree", "N/A", NA),
    foo2016 = c(11, 4, 3, 2, 1, NA),
    foo2017 = c(12, 6, 5, 4, 5, NA)
  )

mytables_in_a_list <- list(d1, d2)

# combine into a single table
mytables_df <- bind_rows(mytables_in_a_list, .id="table")

# a single chain instead of function. 
# You could make this a function, but not necessary

mytables_df %>%
  drop_na() %>%
  rename("Options" = options,
         "2016" = foo2016,
         "2017" = foo2017) %>%
  filter(Options %in% c("Strongly Agree", "Agree", "Disagree", "N/A")) %>%
# make sure the options are ordered appropriatelly
  mutate(Options = factor(Options, levels = c(
    "Strongly Agree", "Agree", "Disagree", "N/A"
  ))) %>%
# using `gather` instead of `melt`, but its the same operation
  gather("Year", "Value", -table, -Options) %>% 
  ggplot(data = ., aes(x=Year, y=Value, group=Options, color=Options)) +
  geom_line() +
  geom_point() +
  facet_wrap("table", ncol=2) +
  theme(legend.position = "top")

使这个情节:

在此处输入图片说明

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用粘贴在R中循环绘制图形

来自分类Dev

在Shiny R中绘制图形;使用重复循环绘制数据以进行自动分析

来自分类Dev

使用 R 绘制图形

来自分类Dev

R语言:将循环结果存储到表中

来自分类Dev

将结果存储在R中的for循环内

来自分类Dev

在R中使用dnorm和多边形函数绘制图形

来自分类Dev

如何在R中按标签绘制图形

来自分类Dev

在R中使用'par(mfrow = c())'绘制图形

来自分类Dev

使用R从文本文件绘制图形

来自分类Dev

如何在R中使用ggplot绘制图形

来自分类Dev

使用基于 R 中多列的值绘制图形

来自分类Dev

在R中绘制图

来自分类Dev

无法将 matplotlib 图导出到 Excel 工作表 --- 使用 matplotlib 到 Excel 在 Jupyter 笔记本中绘制图形

来自分类Dev

R中的for循环将迭代一个简单函数并存储结果

来自分类Dev

在NetworkX中绘制图形,将图形区域划分为3

来自分类Dev

将R个多个循环的输出存储到列表中

来自分类Dev

如何将输出存储到r中的for循环中

来自分类Dev

使用R将多个系列的数据绘制到单个制图中

来自分类Dev

无法将雷达图存储到R对象中

来自分类Dev

将 for 循环的输出存储在 Dataframe R 中

来自分类Dev

绘制图形以强调R中当前和期望值的差异

来自分类Dev

将矩阵循环到R中的矩阵

来自分类Dev

R用不同的数据组绘制图形

来自分类Dev

R - 如何从布尔值绘制图形

来自分类Dev

Android:将图像存储在数据库或可绘制图像中

来自分类Dev

使用 R 中的 for 循环函数将输出写入 csv

来自分类Dev

将日期存储在R中

来自分类Dev

将结果存储在 for 循环中作为向量 (r)

来自分类Dev

用下标绘制图例并在R中插入存储的值

Related 相关文章

热门标签

归档