Gin_Salmon Gin_Salmon - 3 months ago 7
R Question

For loop in R, getting the ith and ith+j row entry in a colum

I've got a data table and I want to go into column "x" and get the ith value and the ith + j value, given they meet a condition

Say i've got the following data table "z":

z
weight height length
1: 9.436635 1 79.16808
2: 6.452202 0 86.33170
3: 4.639220 1 60.52781
4: 7.941667 1 33.79673
5: 3.135519 1 68.47615
6: 7.918595 1 69.77795
7: 3.950212 1 49.74780
8: 7.109392 0 58.41541
9: 5.783499 0 51.30477
10: 5.056078 1 78.37624
11: 9.436635 1 51.69053
12: 6.452202 0 18.39108
13: 4.639220 1 48.52367
14: 7.941667 1 20.99888
15: 3.135519 1 29.77180


I want to write something which will give me the first value in the height column and the second value based on the following condition.

I want to write a loop like:

list1 <- list()
> for (i in -1:nrow(z)){
+ list[[i]] <- z[height == 1 & height+i == 0,]
+ }


So what I want is to get the occurrences where height ==1 and then the immediately following height == 0. I however have found that I can't write a loop like this.

Essentially I want all the rows where I have a 1 followed by a 0 in the height column.

Answer

We can use data.table methods as well by comparing the 'ith' element of 'height' equal to 1 with the 'i+1' equal to 0 (using shift with type = "lead")

library(data.table)
setDT(df1)[height==1 & shift(height, type = "lead")==0]

If we need the row 'i' with 'i+1', we can get the row index (.I) based on the logical condition, then use rep to get the next row and subset the dataset.

i1 <- setDT(df1)[,.I[height==1 & shift(height, type = "lead", fill = 1)==0]]
df1[rep(i1, each=2) + 0:1]
 #    weight height   length
 #1: 9.436635      1 79.16808
 #2: 6.452202      0 86.33170
 #3: 3.950212      1 49.74780
 #4: 7.109392      0 58.41541
 #5: 9.436635      1 51.69053
 #6: 6.452202      0 18.39108