对于R中的循环,在列中获取第i个和第i个+ j行条目

时间:2016-09-01 05:21:03

标签: r for-loop

我有一个数据表,我想进入列“x”并获得 ith 值和 ith + j 值,因为它们符合条件

说我有以下数据表“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

我想写一些东西,它会给我高度列中的第一个值,第二个值基于以下条件。

我想写一个循环:

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

所以我想要的是得到高度== 1然后紧接着高度== 0的出现。但是我发现我不能写这样的循环。

基本上我想要所有的行,其中我有一个1,后面是高度列中的0。

4 个答案:

答案 0 :(得分:4)

我们也可以使用data.table方法,比较'height'的'ith'元素等于1,'i + 1'等于0(shift使用type = "lead" })

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

如果我们需要行'i'和'i + 1',我们可以根据逻辑条件得到行索引(.I),然后使用rep获取下一行和数据集的子集。

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

答案 1 :(得分:2)

这应该有效:

df2 <- df1[df1$height==1 & c(diff(df1$height),0)==-1,]
#> df2
#      weight height   length
#1:  9.436635      1 79.16808
#7:  3.950212      1 49.74780
#11: 9.436635      1 51.69053

编辑:

在OP在一些评论中澄清之后,似乎也应该选择之后符合标准的那一行。实现这一目标的一种可能性是

idx <- which(df1$height == 1 & c(diff(df1$height), 0) == -1)
df1[sort(c(idx,idx+1)),]
#      weight height   length
# 1: 9.436635      1 79.16808
# 2: 6.452202      0 86.33170
# 7: 3.950212      1 49.74780
# 8: 7.109392      0 58.41541
#11: 9.436635      1 51.69053
#12: 6.452202      0 18.39108

数据:

df1 <- structure(list(weight = c(9.436635, 6.452202, 4.63922, 7.941667, 
3.135519, 7.918595, 3.950212, 7.109392, 5.783499, 5.056078, 9.436635, 
6.452202, 4.63922, 7.941667, 3.135519), height = c(1L, 0L, 1L, 
1L, 1L, 1L, 1L, 0L, 0L, 1L, 1L, 0L, 1L, 1L, 1L), length = c(79.16808, 
86.3317, 60.52781, 33.79673, 68.47615, 69.77795, 49.7478, 58.41541, 
51.30477, 78.37624, 51.69053, 18.39108, 48.52367, 20.99888, 29.7718
)), .Names = c("weight", "height", "length"), class = "data.frame", 
row.names = c("1:", "2:", "3:", "4:", "5:", "6:", "7:", "8:", "9:", "10:", 
"11:", "12:", "13:", "14:", "15:"))

答案 2 :(得分:1)

如果您希望之后height==1立即的行height==0,您可以使用filter包中的dplyr lead }和lag

library(dplyr)
result <- z %>% filter((height==1 & lead(height)==0) | (height==0 & lag(height)==1))

filter仅保留满足条件的行。使用您的数据的结果是:

print(result)
##    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

答案 3 :(得分:0)

您可以使用which功能尝试:

db<-data.frame(height=c(1,0,1,1,1,10,1,0,1,0))

for (i in 1:length(db$height)){
  print(which(db$height[i]==1 & db$height[i+1]==0))

}

这将使您第一次出现这种模式。