Reputation: 1145
I have a data set in R. Variable x
is binary (0 or 1), and I need to create a new variable, y
, such that if x[i]
is 0
then y[i]
is 0
, but if x[i]
is 1
, then y[i]=1
, y[i+1]=1
, and y[i+2]=1
. This is what I have done, but it's not working for some reason. Any help is appreciated.
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
}
}
Here is an example of the data:
x y
0 0
0 0
0 0
1 1
0 1
0 1
0 0
0 0
1 1 # this is the last row, so '1' should only be added once.
Upvotes: 1
Views: 2092
Reputation: 8488
Answer to edited question:
First, initialize y
to all zeros, and then check x
only for ones (do nothing if you find a zero):
mydata$y <- 0
for (i in 1:nrow(mydata))
if(mydata$x[i] == 1)
mydata$y[i:min((i+2),nrow(mydata))] <- 1
Answer to old question:
You are not indexing mydata$x
in the if
condition. Change to this:
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
}
}
Note that if x[i]==1
and x[i+1]==0
, then you'll do y[i+1]<-1
and then y[i+1]<-0
, changing what you did when checking x[i]==1
. Also, if the last or second to last value in x
is 1
, you'll be trying to set a value in y
beyond its limits when doing y[i+1]<-1
and y[i+2]<-1
, which will give you an error. I doubt this is what you really want.
Example:
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")
You'll get:
Error in
$<-.data.frame
(*tmp*
, "y", value = c(0, 0, 0, 0, 0, 1, 1, : replacement has 11 rows, data has 10
You can try fixing with:
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
}
}
Upvotes: 2
Reputation: 55350
Here it is as a one-liner. Below is a breakdown of the approach
y <- as.numeric(seq_along(x) %in% outer(which(!!x), 0:2, "+"))
if you have an index of the values of x
which are 1
, you simply add 0:2
to each element of those index and you get the index to y
which should be 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
Upvotes: 2