【问题标题】:Using R to count a run since last event in panel data使用 R 计算自面板数据中最后一个事件以来的运行
【发布时间】:2013-05-05 11:35:18
【问题描述】:

我希望您能帮助我使用 R 编程语言创建一个变量,该变量将计算自另一个变量的最后一个事件以来的“运行”。我正在使用的数据集是国家/地区的面板数据,并且是不平衡的。

我将在下面说明我想做的事情。 COUNTRY 和 YEAR 分别是截面标识和时间单位。 COUNTRYYEAR 是两个变量的串联,用于为每个独特的观察创建一个索引。

令 EVENT 为二元指标,标记感兴趣的事件是否存在 (EVENT = 1) 或不存在 (EVENT = 0)。令 COUNTZERO 为离散计数变量,标记自 EVENT 变量上一次观察到 1 以来的时间(此处:年)。令 COUNTONE 为另一个离散计数变量,标记 EVENT 变量的连续计数的运行计数。我想要一个如下所示的数据框:

COUNTRYYEAR COUNTRY YEAR EVENT COUNTZERO COUNTONE
10011950       1    1950  1       0         1
10011951       1    1951  1       0         2
10011952       1    1952  0       1         0 
10011953       1    1953  0       2         0 
10011954       1    1954  0       3         0 
10011955       1    1955  0       4         0 
10011956       1    1956  0       5         0

....

10021950       2    1950  1       0         1
10021951       2    1951  0       1         0
10021952       2    1952  1       0         1
10021953       2    1953  0       1         0
10021954       2    1954  0       2         0
10021955       2    1955  0       3         0
10021956       2    1956  0       4         0

....

10031975       3    1975  1       0         1
10031976       3    1976  1       0         2
10031977       3    1977  1       0         3
10031978       3    1978  1       0         4
10031979       3    1979  0       1         0
10031980       3    1980  0       2         0

....

数据继续。面板数据不平衡。开始时观察到一些国家(在我的插图中:1950),而其他国家则没有。一些国家在时间域的右端之前退出,而其他国家则没有。有些国家/地区的事件全为零,有些国家/地区全为 1。

如何从我拥有的当前 EVENT 变量创建那些运行计数变量?我查看了this solution,但是在运行示例后,它并没有完全创建我想要创建的向量。

任何意见将不胜感激。

此插图的可重现代码如下。

country <- c(1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3) 
year <- c(1950, 1951, 1952, 1953, 1954, 1955, 1956, 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1975, 1976, 1977, 1978, 1979) 
event <- c(1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0) 
Data=data.frame(country=country, year=year, event=event)

【问题讨论】:

  • 您介意提供一个可重现的数据集吗? stackoverflow.com/questions/5963269/…
  • country &lt;- c(1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3) year &lt;- c(1950, 1951, 1952, 1953, 1954, 1955, 1956, 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1975, 1976, 1977, 1978, 1979) event &lt;- c(1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0) Data=data.frame(country=country, year=year, event=event)
  • 如果您阅读了我链接的那篇文章,它解释了如何轻松地制作示例

标签: r panel data-manipulation


【解决方案1】:

您可以使用rleseq 的组合

reps <- c(10, 9, 3)
offsets <- unlist(sapply(reps, seq))
dat <- data.frame(country = rep(1:3, reps), year = 1950 + offsets, event = rbinom(sum(reps), 1, .5))

o <- rle(dat$event)
sequence <- unlist(sapply(o$lengths, seq))
dat$countzero <- sequence
dat$countzero[dat$event != 0] <- 0
dat$countone <- sequence
dat$countone[dat$event != 1] <- 0

给了

> dat
   country year event countzero countone
1        1 1951     0         1        0
2        1 1952     0         2        0
3        1 1953     0         3        0
4        1 1954     0         4        0
5        1 1955     1         0        1
6        1 1956     0         1        0
7        1 1957     0         2        0
8        1 1958     1         0        1
9        1 1959     0         1        0
10       1 1960     1         0        1
11       2 1951     0         1        0
12       2 1952     1         0        1
13       2 1953     1         0        2
14       2 1954     1         0        3
15       2 1955     1         0        4
16       2 1956     0         1        0
17       2 1957     0         2        0
18       2 1958     0         3        0
19       2 1959     1         0        1
20       3 1951     0         1        0
21       3 1952     0         2        0
22       3 1953     0         3        0

【讨论】:

    【解决方案2】:

    这是一个data.table 解决方案sequencerle

    require(data.table)
    DT <- data.table(Data)
    DT[, c("count_zero", "count_one") := {
    rr <- sequence(rle(!event)$lengths)
    list(rr * !event, rr * event)}]
    #     country year event count_zero count_one
    #  1:       1 1950     1          0         1
    #  2:       1 1951     1          0         2
    #  3:       1 1952     0          1         0
    #  4:       1 1953     0          2         0
    #  5:       1 1954     0          3         0
    #  6:       1 1955     0          4         0
    #  7:       1 1956     0          5         0
    #  8:       2 1950     1          0         1
    #  9:       2 1951     0          1         0
    # 10:       2 1952     1          0         1
    # 11:       2 1953     0          1         0
    # 12:       2 1954     0          2         0
    # 13:       2 1955     0          3         0
    # 14:       2 1956     0          4         0
    # 15:       2 1957     0          5         0
    # 16:       2 1958     0          6         0
    # 17:       3 1975     1          0         1
    # 18:       3 1976     1          0         2
    # 19:       3 1977     1          0         3
    # 20:       3 1978     1          0         4
    # 21:       3 1979     0          1         0
    #     country year event count_zero count_one
    

    【讨论】:

    • 非常感谢,也感谢 Dason 的意见。我想这就是我想做的。
    • 我意识到by=country 不是必需的,并进行了编辑。您可能需要再次检查答案。
    • 看起来结果一样。感谢您提供在必须处理现有数据框的范围内工作的解决方案。
    【解决方案3】:

    你可以用这个:

    count_since<-function(trigger)
    {
      i <- seq_along(trigger)
      (i - cummax(i*trigger))*cummax(trigger)
    }
    

    count_sinve(event)count_since(!event) 是电话号码之一 将在您的示例中使用

    count_since(1:100%%5==0)
      [1] 0 0 0 0 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1
     [72] 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-19
      • 2022-12-06
      • 2019-06-06
      相关资源
      最近更新 更多