【问题标题】:aggregate and reshape dataframe in r在 r 中聚合和重塑数据框
【发布时间】:2018-01-12 21:22:59
【问题描述】:

我想获取一个很长的数据框并使其变宽。这是一个例子:

df <- data.frame(date = rep(seq(as.Date("1990/1/1"), as.Date("1999/1/1"), "years"),10), price = seq.int(1, 100), type = c(rep("str",10), rep("str2",10), rep("chr",10), rep("chr2",10), rep("num",10), rep("num2",10), rep("posix",10), rep("posix2",10), rep("date",10), rep("date2",10)))

我希望每一列都有不同的日期,但正如您所见,type 的每一列都有自己的一组日期,从 1990 年到 1999 年。我只希望每个唯一的 date 有一列,然后是一个每个type 的行。那么第 [i,j] 个单元格中的条目将是该类型在一年中的那一天的价格。

所以我可以想象它看起来像:

类型,1990-1-1, 1991-1-1, ..., 1999-1-1

数字, 1, 2, ... , 10

chr, 11, 12, ..., 20

...

日期, 91, 92, ..., 100

【问题讨论】:

    标签: r dplyr


    【解决方案1】:
    library(dplyr)
    library(tidyr)
    
    df%>%
      arrange(date, type)%>%
      group_by(date, type)%>%
      slice(1)%>%
      spread(date, price)
    
    # A tibble: 5 x 11
    # Groups: type [5]
      type   `1990-01-01` `1991-01-01` `1992-01-01` `1993-01-01` `1994-01-01` `1995-01-01` `1996-01-01` `1997-01-01` `1998-01-01` `1999-01-01`
    * <fctr>        <int>        <int>        <int>        <int>        <int>        <int>        <int>        <int>        <int>        <int>
    1 chr              21           22           23           24           25           26           27           28           29           30
    2 date             81           82           83           84           85           86           87           88           89           90
    3 num              41           42           43           44           45           46           47           48           49           50
    4 posix            61           62           63           64           65           66           67           68           69           70
    5 str               1            2            3            4            5            6            7            8            9           10
    

    现在,Nicolas 在每一行和每一列都生成重复项。您必须删除它们,因为您无法在需要单个数值的位置存储向量(如 Nicolas 答案中的错误所指定)。

    【讨论】:

    • 我会将此标记为正确,但如果您愿意,您应该查看我刚刚发布的另一个问题,该问题将相同的问题扩展到我的实际问题。 stackoverflow.com/questions/48235088/…
    【解决方案2】:

    使用 tidyr 很容易:

    library(tidyr)
    spread(df, key = date, value = price)
    
         type 1990-01-01 1991-01-01 1992-01-01 1993-01-01 1994-01-01 1995-01-01 1996-01-01 1997-01-01
    1     chr         21         22         23         24         25         26         27         28
    2    chr2         31         32         33         34         35         36         37         38
    3    date         81         82         83         84         85         86         87         88
    4   date2         91         92         93         94         95         96         97         98
    5     num         41         42         43         44         45         46         47         48
    6    num2         51         52         53         54         55         56         57         58
    7   posix         61         62         63         64         65         66         67         68
    

    【讨论】:

    • 当我运行这段代码时,我得到了错误Error: Duplicate identifiers for rows (21, 31), (81, 91), (41, 51), (61, 71), (1, 11), (22, 32), (82, 92), (42, 52), (62, 72), (2, 12), (23, 33), (83, 93), (43, 53), (63, 73), (3, 13), (24, 34), (84, 94), (44, 54), (64, 74), (4, 14), (25, 35), (85, 95), (45, 55), (65, 75), (5, 15), (26, 36), (86, 96), (46, 56), (66, 76), (6, 16), (27, 37), (87, 97), (47, 57), (67, 77), (7, 17), (28, 38), (88, 98), (48, 58), (68, 78), (8, 18), (29, 39), (89, 99), (49, 59), (69, 79), (9, 19), (30, 40), (90, 100), (50, 60), (70, 80), (10, 20)
    • 我得到的和@InfiniteFlashChess一样
    • 两点:(1)传播来自“tidyr”包(不是“tidyverse”,如[this other answer]()或“dplyr”中错误提到的那样。(2 ) 重复的标识符通常意味着如果您在最后一行和待列变量上运行 duplicated,您会发现重复的值。@InfiniteFlashChess 仅使用 slice 获取第一个值。另一种选择可能是添加次要 ID,类似于 df %&gt;% group_by(date, type) %&gt;% mutate(id = sequence(n())) %&gt;% unite(key, type, id) %&gt;% spread(date, price)
    猜你喜欢
    • 2019-01-07
    • 1970-01-01
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 2017-02-11
    相关资源
    最近更新 更多