首页 > 解决方案 > 基于跨行字符序列的子集数据

问题描述

如何通过连续字符行的模式对 df 进行子集化?在下面的示例中,我想对历史值连续为“TRUE”、“FALSE”、“TRUE”的数据进行子集化。下面的数据有点奇怪,但你明白了!

value <- c(1/1/16,1/2/16, 1/3/16, 1/4/16, 1/5/16, 1/6/16, 1/7/16, 1/8/16, 1/9/16, 1/10/16)

history <- c("TRUE", "FALSE", "TRUE", "TRUE", "FALSE", "TRUE", "TRUE", "TRUE", "FALSE", "TRUE")

df <- data.frame(value, history)
df

         value history  
1  0.062500000    TRUE  
2  0.031250000   FALSE  
3  0.020833333    TRUE  
4  0.015625000    TRUE  
5  0.012500000   FALSE  
6  0.010416667    TRUE  
7  0.008928571    TRUE  
8  0.007812500    TRUE  
9  0.006944444   FALSE  
10 0.006250000    TRUE  

我试过grepl了,但这适用于字符串 - 而不是跨行连续的字符序列。

输出将与上面的 df 相同,但没有第 7 行,因为它不遵循上述模式。

标签: r

解决方案


你可以做...

s = c("TRUE", "FALSE", "TRUE")

library(data.table)
w = as.data.table(embed(history, length(s)))[as.list(s), on=paste0("V", seq_along(s)), which=TRUE]

df$v <- FALSE
df$v[w + rep(seq_along(s)-1L, each=length(s))] <- TRUE

         value history     v
1  0.062500000    TRUE  TRUE
2  0.031250000   FALSE  TRUE
3  0.020833333    TRUE  TRUE
4  0.015625000    TRUE  TRUE
5  0.012500000   FALSE  TRUE
6  0.010416667    TRUE  TRUE
7  0.008928571    TRUE FALSE
8  0.007812500    TRUE  TRUE
9  0.006944444   FALSE  TRUE
10 0.006250000    TRUE  TRUE

然后,您可以过滤喜欢subset(df, v == TRUE).


这使用 data.table 连接工作,x[i, which=TRUE]它查找i = as.list(s)x = embed(history, length(s))报告x匹配的行:

> as.data.table(as.list(s))
     V1    V2   V3
1: TRUE FALSE TRUE

> as.data.table(embed(history, length(s)))
      V1    V2    V3
1:  TRUE FALSE  TRUE
2:  TRUE  TRUE FALSE
3: FALSE  TRUE  TRUE
4:  TRUE FALSE  TRUE
5:  TRUE  TRUE FALSE
6:  TRUE  TRUE  TRUE
7: FALSE  TRUE  TRUE
8:  TRUE FALSE  TRUE

w + rep(...)与@GGrothendieck 的相同,只是outer(...)这里w包含比赛开始的位置,而不是结束的位置。


推荐阅读