识别、提取和计算序列中的模式

问题描述 投票:0回答:1

我正在使用一个仅包含两列的数据框,其中一列对应于虚拟机生成的唯一 ID,第二列包含一个名称。但是,此特定列也可能包含字符串“ERROR”。

目标是创建一个脚本,使我们能够在每次找到字符串“ERROR”时进行识别,并捕获其周围的姓氏和后续名称以及分配给字符串“ERROR”的唯一 ID。为了说明这一点,让我们看一下下面的例子:

如果我有这些数据:

身份证 姓名
1 詹姆斯
3 错误
6 喀拉斯
88 凯莉
53 迈克尔
55 错误
7 辛迪
834 喀拉斯

然后我们想得出以下列表:

身份证 姓名
3 詹姆斯·凯拉斯
55 迈克尔-辛迪

这是因为找到的第一个字符串“ERROR”的 ID 为 3,位于 James(错误之前)和 Keras(错误之后)之间,下一个“ERROR”的 ID 为 55,位于 Micheal 和 Cindy 之间什么如果“ERROR”是列表的顶部或底部,那么我们应该只包含我们发现的任何名称,可以说“NA-NAME”是在顶部找到的错误...

但这就是棘手的地方;如果我们遇到一个包含连续字符串“ERROR”的序列,我们应该始终使用按降序排列的最后一个字符串作为“指南”:

如果我有这个数据集

身份证 姓名
1 詹姆斯
3 错误
6 错误
88 错误
53 裘德
55 错误
7 辛迪
834 喀拉斯

那么我们就会想要

身份证 姓名
88 詹姆斯-裘德
55 裘德-辛迪

这是因为字符串 ERROR 连续重复了 3 次,但最后一次在 ID 88 处,这意味着我们将以此为参考并记录其前后的名称。另一种看待这一问题的方法是将字符串“ERROR”视为一个块,因此我们将记录每个字符串“ERROR”块之前和之后的名称。

r sequence
1个回答
1
投票

我们可以创建一个函数来执行此操作

f1 <- function(dat) {

    subdat1 <- subset(dat, !duplicated(with(rle(NAMES == "ERROR"), 
           rep(seq_along(values), lengths)), fromLast = TRUE))
    subdat2 <- subset(dat, !duplicated(with(rle(NAMES == "ERROR"), 
          rep(seq_along(values), lengths))))
    ind <- which(subdat1$NAMES == "ERROR")
    do.call(rbind, lapply(ind[c(TRUE, diff(ind) > 1)], function(i) 
        data.frame(ID = subdat1$ID[i],NAMES = paste(subdat1$NAMES[i-1], 
        subdat2$NAMES[i+1], sep="-"))))
}

-测试

> f1(df1)
  ID         NAMES
1  3   James-Keras
2 55 Micheal-Cindy
> f1(df2)
  ID      NAMES
1 88 James-Jude
2 55 Jude-Cindy

数据

df1 <- structure(list(ID = c(1L, 3L, 6L, 88L, 53L, 55L, 7L, 834L), NAMES = c("James", 
"ERROR", "Keras", "Kelly", "Micheal", "ERROR", "Cindy", "Keras"
)), class = "data.frame", row.names = c(NA, -8L))

df2 <- structure(list(ID = c(1L, 3L, 6L, 88L, 53L, 55L, 7L, 834L), NAMES = c("James", 
"ERROR", "ERROR", "ERROR", "Jude", "ERROR", "Cindy", "Keras")), 
 class = "data.frame", row.names = c(NA, 
-8L))
© www.soinside.com 2019 - 2024. All rights reserved.