比较聚集 (tidyr) 和融化 (reshape2)

Posted

技术标签:

【中文标题】比较聚集 (tidyr) 和融化 (reshape2)【英文标题】:Comparing gather (tidyr) to melt (reshape2) 【发布时间】:2014-12-19 14:28:08 【问题描述】:

我喜欢 reshape2 包,因为它让生活变得如此轻松。通常,Hadley 会在他以前的包中进行改进,以实现流线型、更快运行的代码。我想我会试一试 tidyr,从我读到的内容中,我认为 gatherreshape2 中的 melt 非常相似。但是在阅读了文档后,我无法让 gather 完成与 melt 相同的任务。

数据视图

以下是数据视图(实际数据以dput 形式在帖子末尾):

  teacher yr1.baseline     pd yr1.lesson1 yr1.lesson2 yr2.lesson1 yr2.lesson2 yr2.lesson3
1       3      1/13/09 2/5/09      3/6/09     4/27/09     10/7/09    11/18/09      3/4/10
2       7      1/15/09 2/5/09      3/3/09      5/5/09    10/16/09    11/18/09      3/4/10
3       8      1/27/09 2/5/09      3/3/09     4/27/09     10/7/09    11/18/09      3/5/10

代码

这是melt 时尚的代码,我在gather 的尝试。我怎样才能让gathermelt 做同样的事情?

library(reshape2); library(dplyr); library(tidyr)

dat %>% 
   melt(id=c("teacher", "pd"), value.name="date") 

dat %>% 
   gather(key=c(teacher, pd), value=date, -c(teacher, pd)) 

期望的输出

   teacher     pd     variable     date
1        3 2/5/09 yr1.baseline  1/13/09
2        7 2/5/09 yr1.baseline  1/15/09
3        8 2/5/09 yr1.baseline  1/27/09
4        3 2/5/09  yr1.lesson1   3/6/09
5        7 2/5/09  yr1.lesson1   3/3/09
6        8 2/5/09  yr1.lesson1   3/3/09
7        3 2/5/09  yr1.lesson2  4/27/09
8        7 2/5/09  yr1.lesson2   5/5/09
9        8 2/5/09  yr1.lesson2  4/27/09
10       3 2/5/09  yr2.lesson1  10/7/09
11       7 2/5/09  yr2.lesson1 10/16/09
12       8 2/5/09  yr2.lesson1  10/7/09
13       3 2/5/09  yr2.lesson2 11/18/09
14       7 2/5/09  yr2.lesson2 11/18/09
15       8 2/5/09  yr2.lesson2 11/18/09
16       3 2/5/09  yr2.lesson3   3/4/10
17       7 2/5/09  yr2.lesson3   3/4/10
18       8 2/5/09  yr2.lesson3   3/5/10

数据

dat <- structure(list(teacher = structure(1:3, .Label = c("3", "7", 
    "8"), class = "factor"), yr1.baseline = structure(1:3, .Label = c("1/13/09", 
    "1/15/09", "1/27/09"), class = "factor"), pd = structure(c(1L, 
    1L, 1L), .Label = "2/5/09", class = "factor"), yr1.lesson1 = structure(c(2L, 
    1L, 1L), .Label = c("3/3/09", "3/6/09"), class = "factor"), yr1.lesson2 = structure(c(1L, 
    2L, 1L), .Label = c("4/27/09", "5/5/09"), class = "factor"), 
        yr2.lesson1 = structure(c(2L, 1L, 2L), .Label = c("10/16/09", 
        "10/7/09"), class = "factor"), yr2.lesson2 = structure(c(1L, 
        1L, 1L), .Label = "11/18/09", class = "factor"), yr2.lesson3 = structure(c(1L, 
        1L, 2L), .Label = c("3/4/10", "3/5/10"), class = "factor")), .Names = c("teacher", 
    "yr1.baseline", "pd", "yr1.lesson1", "yr1.lesson2", "yr2.lesson1", 
    "yr2.lesson2", "yr2.lesson3"), row.names = c(NA, -3L), class = "data.frame")

【问题讨论】:

您可能对this comparison of the reshape2 and tidyr +dplyr packages 感兴趣。我使用 Air quality 示例和 French Fries 示例来比较 reshape2 melt() 和 dcast() 函数与 tidyr gather() 和 spread() 函数以及 dplyr group_by() 和 summarise() 函数的使用情况。 【参考方案1】:

您的gather 行应如下所示:

dat %>% gather(variable, date, -teacher, -pd)

这表示“收集除teacherpd 之外的所有变量,调用新键列'变量'和新值列'日期'。”


作为解释,请注意help(gather) 页面中的以下内容:

 ...: Specification of columns to gather. Use bare variable names.
      Select all variables between x and z with ‘x:z’, exclude y
      with ‘-y’. For more options, see the select documentation.

由于这是一个省略号,要收集的列的规范作为单独的(裸名)参数给出。我们希望收集除teacherpd 之外的所有列,因此我们使用-

【讨论】:

语法现在非常有意义。我只是以前没见过。感谢您的出色回应。 @BenBolker 我更喜欢这样。它可以帮助我对大脑中的事物进行分组。它也可以减少击键次数。【参考方案2】:

在 tidyr 1.0.0 中,此任务通过更灵活的 pivot_longer() 完成。

等效的语法是

library(tidyr)
dat %>% pivot_longer(cols = -c(teacher, pd), names_to = "variable", values_to = "date")

相应地,“将除teacherpd 之外的所有内容都旋转得更长,将新变量列称为“变量”,将新值列称为“日期”。

请注意,长数据首先按前一个数据帧中被旋转的列的顺序返回,这与 gather 不同,后者按新变量列的顺序返回。要重新排列生成的 tibble,请使用 dplyr::arrange()

【讨论】:

【参考方案3】:

我的解决方案

    dat%>%
    gather(!c(teacher,pd),key=variable,value=date)

【讨论】:

以上是关于比较聚集 (tidyr) 和融化 (reshape2)的主要内容,如果未能解决你的问题,请参考以下文章

R语言将dataframe长表转化为宽表实战:使用reshape函数使用tidyr包的spread函数使用data.table

R语言将dataframe宽表转化为长表实战:使用data.table使用tidyr包gather函数使用reshape2包

R语言—tidyr

R----tidyr包介绍学习

如何使用 reshape r “解开”数据

透视逆透视:R语言(reshape2tidyverse),Excel,Python