在R中使用For循环创建一个新变量

时间:2013-12-08 04:38:24

标签: r if-statement for-loop

我在R中有一个数据集。变量x是二进制(0或1),我需要创建一个新变量y,这样如果x[i]是{ {1}}然后0y[i],但如果0x[i],则1y[i]=1y[i+1]=1 。这就是我所做的,但由于某些原因它不起作用。任何帮助表示赞赏。

y[i+2]=1

以下是数据示例:

for (i in 1:length(mydata$x) ) {    
  if(mydata$x==1) {
    mydata$y[i] <- 1
    mydata$y[i+1] <- 1
    mydata$y[i+2] <- 1
  } else {
    mydata$y[i] <- 0
  }    
}

2 个答案:

答案 0 :(得分:2)

回答编辑过的问题:

首先,将y初始化为全零,然后仅检查x(如果找到零则不执行任何操作):

mydata$y <- 0
for (i in 1:nrow(mydata))
  if(mydata$x[i] == 1)
    mydata$y[i:min((i+2),nrow(mydata))] <- 1

回答旧问题:

您未在mydata$x条件中为if编制索引。改为:

for (i in 1:length(mydata$x) ) {
  if(mydata$x[i] == 1) { # here
    mydata$y[i] <- 1
    mydata$y[i+1] <- 1
    mydata$y[i+2] <- 1
  } else {
    mydata$y[i] <- 0
  }
}

请注意,如果x[i]==1x[i+1]==0,那么您将y[i+1]<-1然后y[i+1]<-0,更改您在检查x[i]==1时所执行的操作。另外,如果x中的最后一个或倒数第二个值为1,那么在执行y和{y[i+1]<-1时,您将尝试将y[i+2]<-1中的值设置为超出其限制{1}},这会给你一个错误。我怀疑这是你真正想要的。

示例:

mydata <- structure(list(x = c(0L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 0L, 1L), 
            y = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), .Names = c("x", 
            "y"), row.names = c(NA, -10L), class = "data.frame")

你会得到:

  

$<-.data.frame中的错误(*tmp*,“y”,值= c(0,0,0,0,0,1,1,:     替换有11行,数据有10行

您可以尝试修复:

for (i in 1:length(mydata$x) ) {
  if(mydata$x[i] == 1) {
    mydata$y[i:min((i+2),nrow(mydata))] <- 1
  } else {
    mydata$y[i] <- 0
  }
}

答案 1 :(得分:2)

矢量化方法

这里是一个单行。以下是方法的细分

y <- as.numeric(seq_along(x) %in% outer(which(!!x), 0:2, "+"))


如果您的x值的索引为1,则只需将0:2添加到这些索引的每个元素中,即可获得y的索引应该是1

y <- rep(0, length(x))

inds <- which(x==1)

## add c(0, 1, 2) to each element of inds
inds <- outer(inds, 0:2, "+")

## make it into a vector
inds <- unique(as.vector(inds))

y[inds] <- 1