快速拉取前一行中具有不同值的data.frame行

时间:2017-02-07 18:18:36

标签: r dataframe

我感兴趣的是从data.frame中提取信息,其中数据框中给定条目的值与前一个不同。这是一个示例框架:

val1

我有兴趣提取第2行和第3行中的信息,其中val1从1更改为2.我可以通过迭代数据框中的每个条目来跟踪前一个{{1这样当它改变时我可以拉出两个相关的行,但是我想知道在数据帧非常大时是否有更快或更有效的方法。 R通常比迭代更快地提取信息,但我不确定在这里使用什么。

4 个答案:

答案 0 :(得分:2)

一种方法是使用diff和逻辑子集:

keepers <- diff(df$val1)
df[as.logical(c(0, keepers) + c(keepers, 0)),]
  name val1 val2
2    a    1   11
3    a    2   12

diff捕获值的变化。将0添加并附加以捕获更改后的第一行和更改前的最后一行,并将这些向量相加,得到1和0的向量。 as.logical将其转换为逻辑向量,用于对行进行子集化。

答案 1 :(得分:2)

使用diff,您可以利用diff为您提供的值小于行数的事实。用:

which(diff(df$val1)==1) + 0:1
# instead of '==1' you can also use '>0' or '!=0': which(diff(df$val1)!=0) + 0:1

您获得之前行的索引和更改后的行:

> which(diff(df$val1)==1) + 0:1
[1] 2 3

因此:

df[which(diff(df$val1)==1) + 0:1, ]

产生了预期的结果:

  name val1 val2
2    a    1   11
3    a    2   12

另一个不错的R-tric正在比较headtail的结果:

which(head(df$val1,-1) != tail(df$val1,-1)) + 0:1

这导致相同的索引(当然!)。

答案 2 :(得分:1)

这与选择组的第一行和最后一行基本相同。从那里你可以删除第一行和最后一行。一个简单的数据表解决方案是:

library(data.table)
zz=data.table(df)
yy=zz[, .SD[c(1,.N)], by=val1]
yy[2:(nrow(yy)-1)]

答案 3 :(得分:0)

我们可以使用lag中的dplyr来获取与前一个不相似的行的索引,然后通过从该索引中减去1来选择上面的一行。

library(dplyr)
i1 <- which(df$val1 != lag(df$val1))
df[sort(c(i1, i1-1)),]

#name val1 val2
#2    a    1   11
#3    a    2   12

另一个例子,

df <- data.frame(name=rep("a", 7),val1=c(1,1,2,2,2,3, 3), val2=c(10,11,12,13,14, 15, 16))
df
df
#  name val1 val2
#1    a    1   10
#2    a    1   11
#3    a    2   12
#4    a    2   13
#5    a    2   14
#6    a    3   15
#7    a    3   16

i1 <- which(df$val1 != lag(df$val1))
df[sort(c(i1, i1-1)),]

#  name val1 val2
#2    a    1   11
#3    a    2   12
#5    a    2   14
#6    a    3   15