【问题标题】:How to plot the numbers in each of 10 columns for one row in a line chart如何为折线图中的一行绘制 10 列中每一列的数字
【发布时间】:2020-12-05 20:01:02
【问题描述】:

这看起来很简单。我可以在 Excel 中轻松完成,但我想通过 R 自动化该过程。我已经安装了 ggplot2。使用 RStudio,我已读入我的 CSV 文件。

生成的数据框有 200 多行,每行都是新罕布什尔州的一个城镇。第一列标题为“城镇”,下面的每一行都有城镇的文本名称(例如,“Concord”或“Lancaster”)。第 2 列包含每个城镇的数字(每个小学生的支出),CSV 文件中该列的标题为“01/02 Elem PPE” - 但在使用 View 时显示为“X01.02.Elem.PPE” ()。第 3 列对每个城镇都有相似的数字,其在 View() 中的标题是“X02.03.Elem.PPE”。第 4 列到第 11 列类似。

我只想为一行(一个城镇)绘制第 2-11 列中的数字的折线图。它将显示该镇每个学生的支出随时间的变化情况。一定有一个简单的方法可以做到这一点,但我找不到。

请帮忙。我今年 77 岁,在 3-5 年前有一些编程经验,但昨天才刚接触 R 和 Rstudio。

【问题讨论】:

  • 嗨@DouglasHall,欢迎使用 StackOverflow 和 R!如果您可以在问题中添加更多数据,它将帮助其他人回答。请运行命令dput(head(df,10))(并将df 替换为您的实际数据框的名称),然后将结果输出添加到您的问题中。只需使用问题左下角的edit 按钮即可添加。

标签: r ggplot2 plot


【解决方案1】:

首先,我将制作一些模仿您的新数据。它应该具有或多或少相同的属性。

library(glue)
library(tidyverse)
set.seed(4314)
mat <- matrix(rpois(40, 5000), ncol=10)
colnames(mat) <- glue("X{sprintf('%2.0f', 1:10)}.{sprintf('%2.0f', 2:11)}.Elem.PPE", sep="") %>% 
  gsub(". ", ".0", ., fixed=TRUE) %>% 
  gsub("X ", "X0", ., fixed=TRUE)

df <- tibble(town = c("Concord", "Lancaster", "Manchester", "Nashua"))
df <- bind_cols(df, as_tibble(mat))

现在,这就是你要开始的地方。我将假设您将 csv 读入一个名为 df 的对象中。为了使绘图更容易,您应该做的第一件事是将数据从宽格式(每次观察 1 行和 10 列)转换为每次观察 1 列和 10 行的长格式。我将把它保存在一个名为df2 的对象中。 pivot_longer 函数在 tidyr 包中。第一个参数是您想要从宽格式更改为长格式的列,在这种情况下,它是 except town 的所有内容。然后你告诉它列名的变量名和值的变量名。然后,我只是使用几个正则表达式从X01.02.Elem.PPE01/02 用于绘图目的。

df2 <- df %>% 
  pivot_longer(-town, names_to="time", values_to="val") %>% 
  mutate(time = gsub("X(.*)\\.Elem\\.PPE", "\\1", time), 
         time = gsub("\\.", "/", time))

生成的数据框如下所示:

# # A tibble: 40 x 3
#   town    time    val
#   <chr>   <chr> <int>
# 1 Concord 01/02  4965
# 2 Concord 02/03  4953
# 3 Concord 03/04  5066
# 4 Concord 04/05  5100
# 5 Concord 05/06  4979
# 6 Concord 06/07  5090
# 7 Concord 07/08  5136
# 8 Concord 08/09  5076
# 9 Concord 09/10  5079
# 10 Concord 10/11  4945

接下来,我们可以为一个地方绘制一个图(在我们考虑自动化之前)。让我们试试康科德。首先,我们将保存要放在 x 轴上的值:

xlabs <- unique(df2$time)

接下来,我们可以使用ggplot() 来制作情节。在下面的代码中,我们首先将数据框传送到过滤器,该过滤器将提取单个城镇的值。过滤后的数据帧通过管道传送到ggplot() 函数中。由于数据框中的time是一个字符向量,所以我们需要把它变成一个因子,然后再变成一个数字来制作线图。我们添加线几何来绘制线。然后我们用scale_x_continuous() 更改x 轴标签。 labs() 函数更改 x 轴和 y 轴的轴标签。最后,ggtitle() 将标题放在情节的顶部。我也喜欢theme_bw() 而不是灰色背景,但这完全是个人喜好问题。结果图如下所示:

df2 %>% filter(town == "Concord") %>% 
  ggplot(aes(x=as.numeric(as.factor(time)), y=val)) + 
  geom_line() + 
  scale_x_continuous(breaks=1:10, labels = xlabs) + 
  labs(x="Time", y="Spending per Pupil") + 
  ggtitle("Concord") + 
  theme_bw()

现在,您提到的下一部分是自动化 - 您希望对原始数据框的每一行都执行此操作。我们可以这样做。首先,untown 从数据中获取town 的唯一值。 for() 循环从 1 循环到 untown 中的值数。然后你可以看到"Concord"在上一个图中的位置,我们现在有untown[i]。我们还在末尾使用ggsave(),并将城镇名称和.png 粘贴在一起。这将为 R 的工作目录中的每个城镇绘制不同的图。

untown <- unique(df2$town)
for(i in 1:length(untown)){
  df2 %>% filter(town == untown[i]) %>% 
    ggplot(aes(x=as.numeric(as.factor(time)), y=val)) + 
    geom_line() + 
    scale_x_continuous(breaks=1:10, labels = xlabs) + 
    labs(x="Time", y="Spending per Pupil") + 
    ggtitle(untown[i]) + 
    theme_bw()
  ggsave(glue("{untown[i]}.png"), width=9, height=6)
}

【讨论】:

    猜你喜欢
    • 2021-06-30
    • 2019-11-18
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    • 2019-04-13
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    相关资源
    最近更新 更多