我感兴趣的是从data.frame中提取信息,其中数据框中给定条目的值与前一个不同。这是一个示例框架:
val1
我有兴趣提取第2行和第3行中的信息,其中val1
从1更改为2.我可以通过迭代数据框中的每个条目来跟踪前一个{{1这样当它改变时我可以拉出两个相关的行,但是我想知道在数据帧非常大时是否有更快或更有效的方法。 R通常比迭代更快地提取信息,但我不确定在这里使用什么。
答案 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正在比较head
和tail
的结果:
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