【问题标题】:generate a variable according to the time-shift of another variable in r根据r中另一个变量的时移生成一个变量
【发布时间】:2024-07-07 05:55:02
【问题描述】:

我有一个这样的数据框

year  id  employment    
1998  1   0
2000  1   0
2002  1   0
2004  1   0 
1998  2   0
2000  2   0
2002  2   1
2004  2   1
1998  3   0
2000  3   1
2002  3   1
2004  3   1

我想创建一个新变量“spell”,它指示每个人在什么时间点从失业(就业=0)转变为就业(就业=1)状态。换句话说,我想要这种形式的东西

year  id  employment   spell 
    1998  1   0            0
    2000  1   0            0
    2002  1   0            0
    2004  1   0            0
    1998  2   0            3
    2000  2   0            3
    2002  2   1            3
    2004  2   1            3
    1998  3   0            2
    2000  3   1            2
    2002  3   1            2
    2004  3   1            2

如您所见,个体 1 显示变量“spell”的值为 0,因为他没有找到工作(变量就业在与他相关的所有观察中保持为零)。另一方面,个人 2 显示法术等于 3,因为他在第三次观察(年=2002)找到了工作,而个人 3 在第二次观察(年=2000)。 有没有人有任何建议做这样的事情?非常感谢您的宝贵时间。

【问题讨论】:

    标签: r


    【解决方案1】:

    这是一个base R 选项

    transform(DF, spell = ave(
      employment,
      id,
      FUN = function(x)
        ifelse(all(x == 0), 0, which(cumsum(x) == 1))
    ))
    #   year id employment spell
    #1  1998  1          0     0
    #2  2000  1          0     0
    #3  2002  1          0     0
    #4  2004  1          0     0
    #5  1998  2          0     3
    #6  2000  2          0     3
    #7  2002  2          1     3
    #8  2004  2          1     3
    #9  1998  3          0     2
    #10 2000  3          1     2
    #11 2002  3          1     2
    #12 2004  3          1     2
    

    基本思想是寻找第一个1的位置——which(cumsum(x) == 1)——每组id。但是因为在id == 1 的组中没有我们需要ifelse 来处理这种情况。

    数据

    DF <- structure(list(year = c(1998L, 2000L, 2002L, 2004L, 1998L, 2000L, 
    2002L, 2004L, 1998L, 2000L, 2002L, 2004L), id = c(1L, 1L, 1L, 
    1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L), employment = c(0L, 0L, 0L, 
    0L, 0L, 0L, 1L, 1L, 0L, 1L, 1L, 1L)), .Names = c("year", "id", 
    "employment"), class = "data.frame", row.names = c(NA, -12L))
    

    【讨论】:

    • 非常感谢你们两个!!它完美地工作:)
    【解决方案2】:

    还有一个:)

    # create data
    rm(list = ls())
    help = c(1998,  1,   0, 2000,  1,   0, 2002,  1,   0, 2004,  1,   0, 1998,  2,   0, 2000,  2,   0, 2002,  2,   1, 2004,  2,   1, 1998,  3,   0, 2000,  3,   1, 2002,  3,   1, 2004,  3,   1)
    help = matrix(help, nrow = length(help)/3, ncol = 3, byrow = T)
    data = data.frame(help)
    names(data) = c("year", "id", "employment")
    data
    
    # create desired variable
    help2 = tapply(data$employment, data$id , function(f) ifelse(sum(f == 1, na.rm = T) > 0, sum(f == 0, na.rm = T)+1, 0))
    help2 = data.frame(help2)
    help2$id = rownames(help2)
    data = merge(data, help2, by = "id")
    data
    

    【讨论】:

      【解决方案3】:

      此 sn-p 假设您的数据在 df 中,并且 id 是从 1 开始的连续整数:

      #assume your data is in df
      df1 <- reshape(df, idvar="year", timevar="id", direction="wide")
      pivoted <- subset(df1, select = -c(year))
      m <- diff(as.matrix(pivoted))
      m[is.na(m)] <- 0
      df2 <- apply(m, 2, cummax)
      df3 <- apply(df2,2, cumsum)
      x <- df3[nrow(df3),]
      y <- 1 + nrow(df1) - x
      y[y == as.numeric(1+nrow(df1))] <- 0
      
      # assign new column
      df$spell <- y[df$id]
      

      【讨论】: