首页 文章

R中的自动序列识别

提问于
浏览
0

我在R中使用一些顺序数据 . 具体来说,我有一个整数列表,它以各种顺序出现多次 . 我想要做的是创建一些代码,可以识别出现了多少不同的序列 .

目前,我是手动完成的 . 我预定义了存在的模式并应用了一个计算事件的函数 .

我首先使用RMYSQL来生成存储在变量product_process_history_joined中的查询 . 然后,我创建了一个我感兴趣的数据列表,它存储在变量数据中 . 然后,我定义我的函数应该处理哪些模式,最后我应用我的函数来计算出现次数 .

代码:

product_process_history_joined<-dbGetQuery(con,"SELECT * 
                                       FROM product, process_history
                                       WHERE product.idproduct =    process_history.product_idproduct")

data<-product_process_history_joined$process_types_idprocess_types

pat <- c(1,2,4,5,6)
x <- sapply(1:(length(data)-length(pat)), function(x) all(data[x:     (x+length(pat)-1)] == pat))
route<-data[which(x)]
countR<-length(route)



pat1 <- c(1,2,4,5,7,9,7,7,2,5,6,10)
x <- sapply(1:(length(data)-length(pat1)), function(x) all(data[x:     (x+length(pat1)-1)] == pat1))
route1<-data[which(x)]
countR1<-length(route1)

生成并存储在数据变量中的数据集如下所示:

[1]  1  4  5  6  1  4  5  6  1  4  5  6  1  4  5  6  1  4  5  6  1  4  5      6  1  4  5  6  1  4  5  6  1  4  5
[36]  6  1  4  5  6  1  4  5  6  1  4  5  6  1  4  5  6  1  4  5  6  1  4   5  6  1  4  5  6  1  4  5  6  1  4
[71]  5  6  1  4  5  6  1  4  5  6  1  4  5  6  1  2  4  5  6 10  1  2  4  5  7  9  7  7  2  5  6 10  1  2  4
[106]  5  6 10  1  2  4  5  6 10  1  2  4  8  1  2  3  5  7  8  1  2  3  5  6  1  2  3  5  6  1  2  4  5  6 10

这只是列表的一个子集 . 我使用了大约12种不同的图案 . 给定数据集中前两个模式的结果是pat为21,pat1为1 .

2 回答

  • 1

    没有理由进行复兴 . 你可以使用 rollapply

    original_data <- c(1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5,6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4,  5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 2, 4, 5, 6, 10, 1, 2, 4, 5, 7, 9, 7, 7, 2, 5, 6, 10, 1, 2, 4, 5, 6, 10, 1, 2, 4, 5, 6, 10, 1, 2, 4, 8, 1, 2, 3, 5, 7, 8, 1, 2, 3, 5, 6, 1, 2, 3, 5, 6, 1, 2, 4, 5, 6, 10)
    
    pattern2 <- c(1, 4, 5, 6)
    
    library(zoo)
    
    sum(
      rollapply(
        original_data, 
        width = length(pattern2), 
        FUN = function(x, pattern) all(x == pattern), 
        pattern = pattern2
      )
     )
    #[1] 21
    

    如有必要,可以提供更快的解决方案,但这提供了良好的可读性 .

    Edit

    这将提取以1开头的所有不同序列:

    x <- split(original_data, cumsum(original_data == 1))
    unique(x)
    res <- vapply(unique(x), function(x, y) sum(vapply(y, FUN = identical, y = x, FUN.VALUE = TRUE)), y = x, FUN.VALUE = 1L)
    Res <- data.frame(n = res,
                      seq = vapply(unique(x), paste, collapse = ",", FUN.VALUE = "a"))
    #   n                      seq
    #1 21                  1,4,5,6
    #2  4             1,2,4,5,6,10
    #3  1 1,2,4,5,7,9,7,7,2,5,6,10
    #4  1                  1,2,4,8
    #5  1              1,2,3,5,7,8
    #6  2                1,2,3,5,6
    
  • 3

    这绝对不是完成工作的最佳方式,但您可以决定将数据视为字符串,然后使用正则表达式(通过 gregexpr ) .

    original_data <- c(1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5,6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4,  5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 4, 5, 6, 1, 2, 4, 5, 6, 10, 1, 2, 4, 5, 7, 9, 7, 7, 2, 5, 6, 10, 1, 2, 4, 5, 6, 10, 1, 2, 4, 5, 6, 10, 1, 2, 4, 8, 1, 2, 3, 5, 7, 8, 1, 2, 3, 5, 6, 1, 2, 3, 5, 6, 1, 2, 4, 5, 6, 10)
    data_as_string <- paste(original_data, collapse="-")
    pattern1 = "1-2-4-5-6" # Your "pat"
    pattern2 = "1-4-5-6" # Occurs 21 times in your data
    pattern3 = "1-2-4-5-7-9-7-7-2-5-6-10" # Your "pat1"
    
    gregexpr(pattern1,data_as_string)
    # [[1]]
    # [1] 169 207 220 273
    # attr(,"match.length")
    # [1] 9 9 9 9
    # attr(,"useBytes")
    # [1] TRUE
    
    # So if you just want the number of occurrences
    length(gregexpr(pattern1,data_as_string)[[1]])
    # [1] 4
    length(gregexpr(pattern2,data_as_string)[[1]])
    # [1] 21
    length(gregexpr(pattern3,data_as_string)[[1]])
    # [1] 1
    

相关问题