r语言tidyr

这是墨菲的数据定律:您拥有的数据并不总是符合您所需的格式。 并非所有问题都与数据中的错误或空白有关。 有时候,你有广泛的数据需要被 ; 或需要广泛的长数据。

让我们来研究一个例子。 在这里,我将阅读五个美国大都市地区的房价电子表格:波士顿,底特律,费城,旧金山和圣何塞(我称其为硅谷)。 更具体地说,是每两年一次的房价数据,1995年所有城市的房价指数均始于100。该数据从2000年到2018年。

看一下电子表格:



r语言tidyverse包 r语言 tidyr_python

IDG


具有宽格式数据的Excel电子表格

我使用housing_data <- rio::import("housingPrices.xlsx")导入此数据。 如果您想在没有电子表格的情况下继续进行操作,那么创建此数据框的代码位于本文的底部。

这是一种非常人性化的格式。 有时称为“宽”格式。 每个都会区都有其自己的列,您可以向下浏览每列并查看该都会区的移动。

但是,如果要使用ggplot2绘制图形,则需要采用所谓的整齐或“长”格式的数据。 每行只有一个观察值,列名中没有数据。 因此,您可以轻松按城市区分ggplot2颜色。 现在,城市信息位于列名中,而不是数据本身。

另一个例子:如果我想计算每年哪个城市的指数值最高,那么很容易计算出每一行中哪个城市的指数最高。 但是,如果要显示哪个都市区域的索引值最高,则必须从列名称中提取信息。




这是此数据的简洁版本。



r语言tidyverse包 r语言 tidyr_数据分析_02

IDG


具有整齐或长格式的数据的电子表格

每行一个观察值:季度,房价指数值和都会区。 对于一个人而言,扫描并不那么容易,但是对于使用R分析(尤其是使用tidyverse程序包)则要好得多。

因此,如果数据的唯一版本是宽版本,那么如何获得长版本? 一种方式是与tidyr包的gather功能。

gather()至少包含三个参数:第一个是数据框的名称。 第二个是您要用于新类别列的名称,称为键。 第三是新值列所需的名称,称为值。 之后是您要“聚集”到新的键和值列中的所有列。 如果您不提供任何列名,则将收集所有列。 在这种情况下,我们希望收集所有城市列,而不是四分之一列。 我可以用-Quarter排除它。

这段代码创建了一个长整洁的数据版本:

library(tidyr)
housing_data_tidy <- gather(data = housing_data, 
      key = MetroArea, value = IndexValue, -Quarter)

使用ggplot2绘制此版本要容易得多。 只需添加group = MetroArea ,我的图表就会将每个都会区绘制为自己的系列或线条。 color = MetroArea为每行赋予不同的颜色。

library(ggplot2)
ggplot(housing_data_tidy) +
geom_line(aes(x = Quarter, y = IndexValue, 
      group = MetroArea, color = MetroArea))

以下代码为绘图增加了一些自定义:

ggplot(housing_data_tidy) +
  geom_line(aes(x = Quarter, y = IndexValue, 
      group = MetroArea, color = MetroArea)) +
  theme_minimal() +
  theme(panel.border = element_blank(), 
       panel.grid.major = element_blank(),
  panel.grid.minor = element_blank(), 
      axis.line = element_line(colour = "gray")) +
  ylab("") +
  ggtitle("Change in Home Prices in 5 US Metro Areas", 
      subtitle = "Data measured January every 2 years; 
      index starts in 1995 at 100") + 
    theme(plot.title = element_text(hjust = 0.5), plot.subtitle = element_text(hjust = 0.5))

我选择了一个不同的主题,然后通过删除所有背景网格和y轴标签,添加标题和副标题以及将标题和副标题居中进行了调整。 在我重塑之前,我想向您展示一个与ggplot2一起使用的很酷的程序包,称为Directlabels。

在这里,我使用的是刚刚制作的相同的自定义图,但是将其存储在名为my_customized_plot的变量中。 然后,在其上运行direct.label()函数,并使用参数last.points和文本的稍微水平对齐。

library("directlabels")
my_customized_plot <- ggplot(housing_data_tidy) +
  geom_line(aes(x = Quarter, y = IndexValue, 
      group = MetroArea, color = MetroArea)) +
  theme_minimal() +
  theme(panel.border = element_blank(), 
      panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(), 
          axis.line = element_line(colour = "gray")) +
  ylab("") +
  ggtitle("Change in Home Prices in 5 US Metro Areas", 
      subtitle = "Data measured January every 2 years; 
      index starts in 1995 at 100") + 
  theme(plot.title = element_text(hjust = 0.5), 
      plot.subtitle = element_text(hjust = 0.5)) 
direct.label(my_customized_plot, list(last.points, hjust = -0.1))

这是发生了什么:


r语言tidyverse包 r语言 tidyr_数据分析_03

IDG

ggplot2折线图和directlabels软件包

我为每行贴上了一个漂亮的标签,而不是一个传奇! 我很喜欢在某些情节中选择它。

回到重塑。

假设我从一开始就将其作为整洁的数据开始,但是想要使其“宽泛”以创建易于阅读的表格。 基本上从现在的长数据框到第一个版本,我在每个都会区的单独列中显示了该版本。 为此,您需要gather()的反面,即spread()

spread()还将数据,键和值作为参数。 在这种情况下,数据就是您的整洁数据帧。 键是现有列的名称,您希望将每个值都变成自己的列。 对于此数据,它是MetroArea。 我们有一列包含都市圈,我希望每个都市圈都在其自己的列中。 值是现有列的名称,其中包含应散布到新列中的值。 除非您告诉R,否则R可能不确定是否应该将其指定为Index列或Quarter列。

这是代码:

housing_data_wide <- spread(housing_data_tidy,
      key = MetroArea, value = IndexValue)

现在我们回到广泛的数据。

创建初始数据框的代码

housing_data <- data.frame(stringsAsFactors=FALSE,
     Quarter = c("Q1-2000", "Q1-2002", "Q1-2004", "Q1-2006", "Q1-2008",
                 "Q1-2010", "Q1-2012", "Q1-2014", "Q1-2016", "Q1-2018"),
      Boston = c(148.58, 189.41, 234.68, 272.14, 253.33, 227.91, 224.55,
                 237.61, 264.23, 300.96),
     Detroit = c(150.8, 170.34, 181.89, 186.43, 158.29, 117.45, 111.14, 130.59,
                 148.26, 170.92),
        Phil = c(111.73, 132.86, 164.54, 219.74, 234.13, 219.46, 211.24,
                 214.87, 227.5, 258.49),
     SanFran = c(159.11, 195.5, 223.02, 305.88, 291.35, 248.28, 238.37, 306.24,
                 387.34, 447.45),
    SiValley = c(170.74, 205.14, 223.33, 311.17, 293.01, 238.12, 233, 300.89,
                 367.1, 428.45))




翻译自: https://www.infoworld.com/article/3310078/reshape-data-in-r-with-the-tidyr-package.html

r语言tidyr