【问题标题】:how to pivot/unpivot (cast/melt) data frame? [duplicate]如何旋转/取消旋转(投射/融化)数据框? [复制]
【发布时间】:2011-12-20 06:29:21
【问题描述】:

如何“反透视”表格?正确的技术术语是什么?

更新:这个词叫做melt

我有一个国家数据框和每年的数据

Country     2001    2002    2003
Nigeria     1       2       3
UK          2       NA       1

我想拥有类似的东西

Country    Year    Value
Nigeria    2001    1
Nigeria    2002    2
Nigeria    2003    3
UK         2001    2
UK         2002    NA
UK         2003    1

【问题讨论】:

    标签: r pivot-table reshape reshape2


    【解决方案1】:

    我仍然不敢相信我以一个答案击败了安德烈。 :)

    > library(reshape)
    > my.df <- read.table(text = "Country     2001    2002    2003
       + Nigeria     1       2       3
       + UK          2       NA       1", header = TRUE)
    > my.result <- melt(my.df, id = c("Country"))
    > my.result[order(my.result$Country),]
         Country variable value
       1 Nigeria    X2001     1
       3 Nigeria    X2002     2
       5 Nigeria    X2003     3
       2      UK    X2001     2
       4      UK    X2002    NA
       6      UK    X2003     1
    

    【讨论】:

    • 你也打败了我。还可以尝试:check.names=FALSE 在阅读时获得没有 X 前缀的年份,或者 sub("^X","",variable) 稍后将它们剥离;和as.numeric(variable) 转换回数值
    • 谢谢!我想技术术语是“融化”桌子。对吗?
    • 是的——至少这可能是 R 圈子中最常用的术语,这要归功于惊人的 reshape 包(就我而言,它引入了“熔化”和“铸造”的术语知道)
    • +1 那么谁在使用 R 2.14?看看text=read.table 的参数!
    【解决方案2】:

    这个问题的基本 R reshape 方法非常难看,特别是因为名称不是reshape 喜欢的形式。如下所示,第一行 setNames 将列名修改为 reshape 可以使用的名称。

    reshape(
      setNames(mydf, c("Country", paste0("val.", c(2001, 2002, 2003)))), 
      direction = "long", idvar = "Country", varying = 2:ncol(mydf), 
      sep = ".", new.row.names = seq_len(prod(dim(mydf[-1]))))
    

    base R 中更好的替代方法是使用stack,如下所示:

    cbind(mydf[1], stack(mydf[-1]))
    #   Country values  ind
    # 1 Nigeria      1 2001
    # 2      UK      2 2001
    # 3 Nigeria      2 2002
    # 4      UK     NA 2002
    # 5 Nigeria      3 2003
    # 6      UK      1 2003
    

    现在还有用于重塑数据的新工具,例如“tidyr”包,它为我们提供了gather。当然,tidyr:::gather_.data.frame 方法只是调用了reshape2::melt,所以我的这部分答案除了介绍您可能在 Hadleyverse 中遇到的新语法之外,不一定要添加太多内容。

    library(tidyr)
    gather(mydf, year, value, `2001`:`2003`) ## Note the backticks
    #   Country year value
    # 1 Nigeria 2001     1
    # 2      UK 2001     2
    # 3 Nigeria 2002     2
    # 4      UK 2002    NA
    # 5 Nigeria 2003     3
    # 6      UK 2003     1
    

    如果您想要问题中显示的行顺序,则此处的所有三个选项都需要对行进行重新排序。


    第四个选项是使用我的“splitstackshape”包中的merged.stack。与基本 R 的 reshape 一样,您需要将列名修改为包含“变量”和“时间”指示符的名称。

    library(splitstackshape)
    merged.stack(
      setNames(mydf, c("Country", paste0("V.", 2001:2003))),
      var.stubs = "V", sep = ".")
    #    Country .time_1  V
    # 1: Nigeria    2001  1
    # 2: Nigeria    2002  2
    # 3: Nigeria    2003  3
    # 4:      UK    2001  2
    # 5:      UK    2002 NA
    # 6:      UK    2003  1
    

    样本数据

     mydf <- structure(list(Country = c("Nigeria", "UK"), `2001` = 1:2, `2002` = c(2L, 
         NA), `2003` = c(3L, 1L)), .Names = c("Country", "2001", "2002",               
         "2003"), row.names = 1:2, class = "data.frame")   
    

    【讨论】:

    • 列子集的反引号...?为什么。我也刚开始擅长 dplyr。哈哈
    【解决方案3】:

    您可以使用reshape 包中的melt 命令。见这里:http://www.statmethods.net/management/reshape.html

    可能类似于melt(myframe, id=c('Country'))

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-08
      • 2020-05-29
      • 2015-04-04
      • 2019-11-14
      相关资源
      最近更新 更多