条件列创建(水平和垂直条件)

时间:2013-12-08 21:12:02

标签: r if-statement for-loop which

我的起始条件类似于df数据框

df<-data.frame(id=c(rep(2, 3), rep(4, 2)), year=c(2005:2007, 2005:2006), event=c(1,0,0,0,1))

  id year event
1  2 2005     1
2  2 2006     0
3  2 2007     0
4  4 2005     0
5  4 2006     1

我有一系列演员(通过id识别)碰巧在某一年遇到过一个事件。

这里我试图构建的是一系列附加列,用于描述a)事件的距离和b)这种距离是否可观察。

这是我想要获得的。

   id year event evm2 evm1 evp1 evp2 ndm2 ndm1 ndp1 ndp2
1  2 2005     1    0    0    0    0    1    1    0    0
2  2 2006     0    0    1    0    0    1    0    0    1
3  2 2007     0    1    0    0    0    0    0    1    1
4  4 2005     0    0    0    1    0    1    1    0    1
5  4 2006     1    0    0    0    0    1    0    1    1
某个年份发生事件时,

event等于1。当事件在前一年可观察时,evm1等于1。同样,当事件发生在下一年时,evp1为1 - 字母pm代表“加号”和“减号”,数字代表距离日期的距离事件。 对于这些观察中的一些,距离是不可观察的,因为可用时间窗口太短。这是df[1,]的情况,我们不知道在过去几年中是否发生了事件。在这种情况下,ndm1ndm2会被编码1.如果我们考虑案例df[5,],则ndp1(和ndp2)将被编码1。 evnd变量完全以相同的方式工作。但前者告诉我是否在一定距离内存在事件,而后者则揭示这样的距离是否真的可以观察到。

我尝试使用以下嵌套for循环完成此操作,但我没有成功。

lag<-c(-2, -1, 1, 2)
df2<-df
df2[,4:11]<-0
colnames(df2)<-c("id", "year", "event", "evm2",  "evm1",  "evp1",  "evp2",  "ndm2",  "ndm1",  "ndp1",  "ndp2") 


for (i in length(df2$id)) {

  id<-df2[i,1]
  yr<-df2[i,2]
  sta<-3
  sta2<-7

  for (j in lag){

    sta<-sta+1
    sta2<-sta2+1

    if !is.null(df2[df2$id==id & df2$year==yr+j])==TRUE {

      rw<-which(df2[df2$id==id & df2$year==yr+j])

      if (df2[rw,3]==1) df2[i, sta]==1

    } else {

      df2[i, sta2]==1

    }

  }

}

您是否看到任何可能导致错误的原因?我已经疯了两天试图让它发挥作用,如果你能提供帮助,我会非常感激。

1 个答案:

答案 0 :(得分:3)

根据我的评论,这是我想到的潜在重写:

lag.it <- function(x, n = 0L) {
  l <- length(x)
  neg.lag <- min(max(0L, -n), l)
  pos.lag <- min(max(0L, +n), l)
  c(rep(NA, +neg.lag),
    head(x, -neg.lag),
    tail(x, -pos.lag),
    rep(NA, +pos.lag))
}

library(plyr)
ddply(df, "id", transform,
      evm2 = lag.it(event, -2),
      evm1 = lag.it(event, -1),
      evp1 = lag.it(event, +1),
      evp2 = lag.it(event, +2))

#   id year event evm2 evm1 evp1 evp2
# 1  2 2005     1   NA   NA    0    0
# 2  2 2006     0   NA    1    0   NA
# 3  2 2007     0    1    0   NA   NA
# 4  4 2005     0   NA   NA    1   NA
# 5  4 2006     1   NA    0   NA   NA

注意我如何使用NA而不是使用两组变量。虽然我建议您保持这种方式,但通过定义例如,您可以轻松获得所要求的内容。 ndm2is.na(evm2),然后用零替换NA