【问题标题】:count both a set of consecutive values and differences between them in a row连续计算一组连续值和它们之间的差异
【发布时间】:2016-03-03 12:56:15
【问题描述】:

我的原始数据是这样的

df <- structure(list(V = structure(c(4L, 5L, 3L, 7L, 6L, 2L, 1L), .Label = c("132 B26,172 B27,107 B57,104 B59,137 B60,133 B61,103 B62,134 B63,177 B100,123 B133,184 B168,109 B197,103 B198,173 B202,157 B203,143 B266,62 B342,62 B354,92 B355,195 B368,164 B370,52 B468,74 B469,71 B484,98 B494,66 B502,63 B601,133 B622", 
"135A,510A,511A,60 B23,67 B24,70 B25,95 B26,122 B27,123 B27,109 B60", 
"25A,28 B55,31 B56,45 B57,43 B58,5 B59,47 B59,6 B60,69 B60,66 B61", 
"267 B361,786 B363,543 B392", "563 B202,983 B360", "8 B1,12 B35,10 B71,9 B154,51 B179", 
"91 B26,117 B27,117 B28,102 B29,47 B31,96 B63,78 B64,133 B65,117 B66,121 B66,112 B67,127 B100"
), class = "factor")), .Names = "V", class = "data.frame", row.names = c(NA, 
-7L))

感谢@Arkun,我可以使用此功能获得输出

Newdf <- data.frame(v1 = sapply(str_extract_all(df$V, "(?<=[A-Z])\\d+"), toString), stringsAsFactors=FALSE)

从这个输出中,

那我要计算每一行的连续数

第 1 行没有

第 2 行没有

第 3 行有 1 个连续的 55,56,57,58,59,59,60,60,61

第 4 行有两个连续的 26,27,28,29 和 63,64,65,66,66,67

第 5 行没有

第 6 行有 1 个

第 7 行有 6 个 (26,27) (59,60,61,62,63) (197,198) (202,203) (354,355) (468,469) 然后我想添加一列显示差异 在每个连续到下一个之间,

#for example (26,27) and (59,60,61,62,63)  is 59-27= 32
#(59,60,61,62,63) and (197,198) is 197-63=134
#(197,198)  and (202,203) is 202-198= 4
#(202,203) and (354,355) is 354-203= 151
#(354,355) and (468,469) is 468-355= 113

所以我的输出会是这样的

            V2              V3
            0               0
            0               0
            1               0
            2               34
            0               0
            1               0
            6            32,134,4,151,113

【问题讨论】:

  • @arkun 作为第 7 行中两个连续集合 (26,27) (59,60,61,62,63) 之间的示例,我将像这样计算它们的距离:在 26 和 26 之间哪个更大? 27,由于第二组是第二组,我检查最小值,所以两者之间的距离将是 59-27
  • 试试sapply(str_extract_all(df$V, "(?&lt;=[A-Z])\\d+"), function(x) {x1 &lt;- as.numeric(x[!duplicated(x)]); sum(rle(diff(x1)==1)$values)})#[1] 0 0 1 2 0 1 6
  • @arkun 我们总是检查一组与该行中的下一组。所以如果我们有 10 个连续的集合,就会像这样第一组的值越大,第二组的采样器值越大,第二组的值越大,第三组的值越小,第三组的值越小第四组的值越大,这将一直持续到没有任何连续的组剩余
  • 您将从上面的代码中得到的第一列。
  • 如果你检查我的代码,我没有在这里使用toString

标签: r


【解决方案1】:

我们可以试试

library(stringr)
library(data.table)
lst1 <- lapply(str_extract_all(df$V, "(?<=[A-Z])\\d+"), 
         as.numeric)
lst1 <- lapply(lst1, sort)
V2 <- sapply(lst1, function(x) {
         x1 <- x[!duplicated(x)]
         sum(rle(diff(x1)==1)$values)})
i1 <- V2 >1
V3 <- rep(0, length(V2))

V3[i1] <- unlist(lapply(lst1[i1], function(v1) {
        gr <- cumsum(c(TRUE,v1[-1]-v1[-length(v1)]>1))
        d1 <- data.table(v1, gr)
        d1[, if(.N >1) .SD, gr
             ][, list(v1[1], v1[.N]) , gr
              ][, {tmp <- V1-shift(V2)
                 list(toString(tmp[!is.na(tmp)]))}]
        }), use.names=FALSE)

d1 <- data.frame(V2, V3, stringsAsFactors=FALSE)
d1
#  V2                   V3
#1  0                    0
#2  0                    0
#3  1                    0
#4  2                   34
#5  0                    0
#6  1                    0
#7  6 32, 134, 4, 151, 113

【讨论】:

  • @Mol 我只使用了你的示例数据。
  • 再次被点赞和接受 :-) 感谢感谢感谢 AKRUN
  • @Mol 谢谢你。你找到解决另一个问题的方法了吗
  • @Mol 看起来值得一些赏金,并且已经发布了 2 个答案
猜你喜欢
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多