【问题标题】:Create equal number of rows for observations in data.tables在 data.tables 中为观察创建相等数量的行
【发布时间】:2020-07-07 07:30:23
【问题描述】:

我有数百个数据集,涵盖了从 1875 年到 2020 年期间的数百个变量。但是,每年的条目数量并不相同,甚至根本没有,所以我想调整数据套。

具体来说,我希望每年的行数相同,并且每年添加的系列仅包含 NA。如果条目最多的年份在数据集中有 5 行,那么所有年份在数据集中都应该有 5 行。如果年份尚未包含在数据集中,则必须为其添加相应的行数和所有变量的 NA。

由于数据集的大小,我想使用 data.tables,但我不知道如何使用 data.table 编码以有效的方式解决这个问题。我之前的尝试主要是循环组合,这使得处理非常慢。对于您的方向,这里是数据集结构的一个最小示例。任何形式的帮助都深表感谢。

First <- 1875; Last <- 2020
Year <- c(1979,1979,1979,1982,1987,1987,1987,1988,1989,1990,1993,1995,1997,1997,1998,1999,2000)
Sums <- c(0.30,1.47,4.05,1.30,1.42,1.86,1.29,0.97,1.54,0.46,0.67,0.98,1.73,0.74,1.70,0.95,0.90)
Days <- c(3,4,3,5,3,3,3,3,7,3,8,10,3,3,3,3,3)

Data <- data.table(Year=Year, Sums=Sums, Days=Days)

理想情况下,该过程将输出具有类似模式的 data.table。为便于阅读,数据集不是以 1875 开头,而是以 1975 开头。

    Year Sums Days
1:  1979 0.30    3 # 1979 has the most observations in the data.table
2:  1979 1.47    4
3:  1979 4.05    3
4:  1982 1.30    5
5:  1982 1.42    3
6:  1982 NA      NA # New observation
7:  1987 1.86    3
8:  1987 1.29    3
9:  1987 0.97    3
10: 1988 1.54    7
11: 1988 NA      NA # New observation
12: 1988 NA      NA # New observation
13: 1989 0.46    3
14: 1989 NA      NA # New observation
15: 1989 NA      NA # New observation
16: 1990 0.67    8
17: 1990 NA      NA # New obeservation
18: 1990 NA      NA # New obeservation
19: 1991 NA      NA # New observation for 1991; year wasn't included previously
20: 1991 NA      NA # New observation for 1991; year wasn't included previously
21: 1991 NA      NA # New observation; year wasn't included 
22: 1992 NA      NA # New observation; year wasn't included 
23: 1992 NA      NA # New observation; year wasn't included 
24: 1992 NA      NA # New observation; year wasn't included 
25: 1993 0.98   10
26: 1993 NA      NA # New observation
27: 1993 NA      NA # New observation
28: 1994 NA      NA # New observation; year wasn't included 
29: 1994 NA      NA # New observation; year wasn't included 
30: 1994 NA      NA # New observation; year wasn't included 
31: 1995 1.73    3
32: 1995 NA      NA # New obeservations
33: 1995 NA      NA # New obeservations
..................

【问题讨论】:

  • 欢迎来到 SO!您能否也分享给定示例的预期输出。
  • 给定一个合适的MWE,当然可以帮助你做你想做的事。但我对这样做非常谨慎。有了这么多数据,我希望您会在某个时候总结您的信息(例如,平均 SumsYear)。在您提出建议时人为地添加零此时会使您的结果产生偏差。你不应该这样做。如果您出于其他原因需要在每个数据框中进行相同数量的观察(我怀疑这不太可能),使用 NA 而不是 0 会更好。
  • 你的例子不起作用——Year 向量中有,,,也许缺少一年?
  • 非常感谢大家!我已经包含了预期的输出并修复了拼写错误。

标签: r data.table


【解决方案1】:

另一个data.table 选项:

Data[, ri := rowid(Year)][
    CJ(Year=seq(min(Year), max(Year), by=1L), ri=seq.int(max(ri))), on=.NATURAL]

或者对于特定范围(FirstLast):

Data[, ri := rowid(Year)][
        CJ(Year=First:Last, ri=seq.int(max(ri))), on=.NATURAL]

【讨论】:

  • 以前从未见过on=.NATURAL
  • data.table v1.12.4(2019 年 10 月 3 日)版本中的第 10 项。 rdrr.io/github/Rdatatable/data.table/f/NEWS.md
  • 谢谢@chinsoon12,我之前没听说过on=.NATURAL,不过很快就会查到!
【解决方案2】:
n <- max(table(Data$Year))
setkey(Data, Year)

Data2 <- Data[J(First:Last), .SD[1:n], by = .EACHI]

或者不设置密钥(感谢 chinsoon12):

Data2 <- Data[J(Year = First:Last), on = .NATURAL, .SD[1:n], by = .EACHI]

示例输出:

Data2[Year %between% c(1996L, 1999L)]
#     Year Sums Days
#  1: 1996   NA   NA
#  2: 1996   NA   NA
#  3: 1996   NA   NA
#  4: 1997 1.73    3
#  5: 1997 0.74    3
#  6: 1997   NA   NA
#  7: 1998 1.70    3
#  8: 1998   NA   NA
#  9: 1998   NA   NA
# 10: 1999 0.95    3
# 11: 1999   NA   NA
# 12: 1999   NA   NA

【讨论】:

  • 谢谢,这解决了我的问题。我使用您的两种方法运行了一些基准测试,您的原始解决方案是迄今为止最快的。
【解决方案3】:

我们可以使用table 函数找到特定年份的最多行数。然后我们可以使用complete 来包含从FirstLast 年份的所有不完整的观察结果,每一年都有n 行。

library(dplyr)
library(tidyr)

n <- max(table(Data$Year))

Data %>%
  group_by(Year) %>%
  mutate(row = row_number()) %>%
  ungroup %>%
  complete(Year = First:Last, row = 1:n, fill = list(Sums = 0, Days = 0))

# A tibble: 438 x 4
#    Year   row  Sums  Days
#   <dbl> <int> <dbl> <dbl>
# 1  1875     1     0     0
# 2  1875     2     0     0
# 3  1875     3     0     0
# 4  1876     1     0     0
# 5  1876     2     0     0
# 6  1876     3     0     0
# 7  1877     1     0     0
# 8  1877     2     0     0
# 9  1877     3     0     0
#10  1878     1     0     0
# … with 428 more rows

【讨论】:

    猜你喜欢
    • 2023-01-13
    • 2019-08-23
    • 1970-01-01
    • 1970-01-01
    • 2017-09-05
    • 2023-04-10
    • 2021-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多