Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R:在数据帧单元中对数据进行排序_R_Regex_Dataframe - Fatal编程技术网

R:在数据帧单元中对数据进行排序

R:在数据帧单元中对数据进行排序,r,regex,dataframe,R,Regex,Dataframe,我有多个列的巨大数据框,其中一列包含这样的数据 No "48.8.1.1." "48.8.1.2." "48.8.2." "48.9." "48.10." "48.11." "48.11.1." "48.11.1.1." "48.11.1.2

我有多个列的巨大数据框,其中一列包含这样的数据

       No  

   "48.8.1.1." 
   "48.8.1.2."
   "48.8.2." 
   "48.9." 
   "48.10." 
   "48.11." 
   "48.11.1." 
   "48.11.1.1." 
   "48.11.1.2." 
   "48.11.1.2.2.2.2.1."      
数据的子顺序中没有固定的顺序

问题:

df$No<-substring(df$No,1,9)
而不是

   "48.11.1.2.1."  
某些值的顺序不正确,如ex:

   "48.11.1.2.2.2.2.1"   
2号是额外的。 如何删除2的额外数字

我确实尝试过一些方法,比如重置索引等,但都不起作用。 需要一些建议。

试试:

编辑::

df$No<-stringr::str_remove_all(df$No,"2.{1,}(?=2.{3,})")
原件::

df$No<-substring(df$No,1,9)
数据:


df假设字符串序列表示大纲中各部分的编号,以下是一种可能的解决方案:

library(data.table)
# reshape to long format
long <- DT[, rn := .I][
  , strsplit(No, "[.]"), by = rn][
    , V1 := as.integer(V1)][
      , lvl := rowid(rn)][]

# find contiguous streaks of rows where there is a gap in levels
nlvl <- long[, .N, keyby = rn][
  , gap := cumsum(c(diff(N), 0L) > 1L)][
    , M := first(N) + 1L, by = gap]

# non-equi anti-join and recast
long[!nlvl[N > M], on = .(rn, lvl >= M, lvl < N)][
  , .(No = paste(V1, collapse = ".")), by = rn]
解释 如果我理解正确的话,字符串序列表示大纲中的部分编号,该编号由于插入虚假的附加级别而被扭曲。OP正在寻找删除这些附加级别的方法

那么,让我们假设一些对大纲各部分进行编号的规则:

  • 节数差距:在同一级别上,节数始终提前1。
    例如,遵循第
    4.1.3节
    
    
    • 通过
      4.1.4
      (在第3节中前进)
    • 或通过
      4.2
      (如果父级为高级)
    • 或通过
      5
      (前进到下一章)
  • 级别差距:子级别始终比父级别低1个级别。子级上的节编号从1开始。
    例如,章节
    4.1.3
    后面可以是
    4.1.3.1
    小节,但不能是
    4.1.3.1.1
    从第3节级别跳到第5小节级别
  • 由于OPs问题可能与情形2有关,我们需要用 与前面行相关的级别差距。作为修复,所有中间剩余水平将被删除。最后一个级别保持不变,因为它的编号可能是正确的

    第一步包括添加行号、拆分
    处的字符串、强制将节号设置为整数以及为每行的级别编号。现在,章节编号采用长格式:

     long
    
    在下一步中,将识别出现在剖面层间隙之后的连续行条纹。节级别是属于一行的元素的数量
    N
    <代码>间隙
    标记在节级别中非法跳转之后出现的所有行
    M
    表示根据上述规则2合法的最高区段等级

    nlvl
    
    在最后一步中,通过非等反连接从
    long
    中消除额外的杂散电平。然后,通过将各部分粘贴在一起重新创建节号

    为了进行比较,我们可以将结果与原始数据结合起来:

    long[!nlvl[N > M], on = .(rn, lvl >= M, lvl < N)][
      , .(No = paste(V1, collapse = ".")), by = rn][DT, on = "rn"]
    
    资料 OP发布的数据的扩展版本

    library(data.table)
    DT <- data.table(No = c(
      "48.8.1.1.", 
      "48.8.1.2.",
      "48.8.2." ,
      "48.9." ,
      "48.10." ,
      "48.11." ,
      "48.11.1." ,
      "48.11.1.1." ,
      "48.11.1.2." ,
      "48.11.1.2.2.2.2.1.",
      "48.11.1.2.2.2.2.2.",
      "48.11.1.2.2.3.",
      "48.11.2.",
      "48.11.2.1.",
      "48.11.2.1.1.",
      "48.11.3.",
      "48.11.3.3.3.1.",
      "50."
    ))
    
    库(data.table)
    
    DT您提供了问题,但提供了没有问题的数据。请编辑您的问题以使其更易于理解。@NelsonGon:嘿,我已经编辑了问题。请包括您迄今为止所做的尝试。我看到您提供了输入数据的示例。还请添加(1)您想要的结果,以及(2)到目前为止您尝试将输入转换为结果的代码。那么为什么
    48.11.1.1
    48.8.1.1.
    不是垃圾?只有当字符串为9个字符但我的字符串没有固定长度时,它才会起作用。请尝试编辑。另外,最好准确地表示数据的外观。使用
    dput
    添加样本数据。非常好。在我注意到你对问题的中间评论和编辑后,我担心测试用例的数量太少,无法充分测试相当复杂的逻辑。耶,我在代码中做了一些更改,现在工作正常。你在代码中做了哪些更改?请让我知道如何改进我的答案-谢谢。
        rn V1 lvl
     1:  1 48   1
     2:  1  8   2
     3:  1  1   3
     4:  1  1   4
     5:  2 48   1
     6:  2  8   2
    [...]
    25:  9 48   1
    26:  9 11   2
    27:  9  1   3
    28:  9  2   4
    29: 10 48   1
    30: 10 11   2
    31: 10  1   3
    32: 10  2   4
    33: 10  2   5
    34: 10  2   6
    35: 10  2   7
    36: 10  1   8
    37: 11 48   1
    38: 11 11   2
    39: 11  1   3
    40: 11  2   4
    41: 11  2   5
    42: 11  2   6
    43: 11  2   7
    44: 11  2   8
    45: 12 48   1
    46: 12 11   2
    47: 12  1   3
    48: 12  2   4
    49: 12  2   5
    50: 12  3   6
    51: 13 48   1
    52: 13 11   2
    53: 13  2   3
    54: 14 48   1
    55: 14 11   2
    56: 14  2   3
    57: 14  1   4
    58: 15 48   1
    59: 15 11   2
    60: 15  2   3
    61: 15  1   4
    62: 15  1   5
    63: 16 48   1
    64: 16 11   2
    65: 16  3   3
    66: 17 48   1
    67: 17 11   2
    68: 17  3   3
    69: 17  3   4
    70: 17  3   5
    71: 17  1   6
    72: 18 50   1
        rn V1 lvl
    
    nlvl
    
        rn N gap M
     1:  1 4   0 5
     2:  2 4   0 5
     3:  3 3   0 5
     4:  4 2   0 5
     5:  5 2   0 5
     6:  6 2   0 5
     7:  7 3   0 5
     8:  8 4   0 5
     9:  9 4   1 5
    10: 10 8   1 5
    11: 11 8   1 5
    12: 12 6   1 5
    13: 13 3   1 5
    14: 14 4   1 5
    15: 15 5   1 5
    16: 16 3   2 4
    17: 17 6   2 4
    18: 18 1   2 4
    
    long[!nlvl[N > M], on = .(rn, lvl >= M, lvl < N)][
      , .(No = paste(V1, collapse = ".")), by = rn][DT, on = "rn"]
    
        rn          No               i.No
     1:  1    48.8.1.1          48.8.1.1.
     2:  2    48.8.1.2          48.8.1.2.
     3:  3      48.8.2            48.8.2.
     4:  4        48.9              48.9.
     5:  5       48.10             48.10.
     6:  6       48.11             48.11.
     7:  7     48.11.1           48.11.1.
     8:  8   48.11.1.1         48.11.1.1.
     9:  9   48.11.1.2         48.11.1.2.
    10: 10 48.11.1.2.1 48.11.1.2.2.2.2.1.
    11: 11 48.11.1.2.2 48.11.1.2.2.2.2.2.
    12: 12 48.11.1.2.3     48.11.1.2.2.3.
    13: 13     48.11.2           48.11.2.
    14: 14   48.11.2.1         48.11.2.1.
    15: 15 48.11.2.1.1       48.11.2.1.1.
    16: 16     48.11.3           48.11.3.
    17: 17   48.11.3.1     48.11.3.3.3.1.
    18: 18          50                50.
    
    library(data.table)
    DT <- data.table(No = c(
      "48.8.1.1.", 
      "48.8.1.2.",
      "48.8.2." ,
      "48.9." ,
      "48.10." ,
      "48.11." ,
      "48.11.1." ,
      "48.11.1.1." ,
      "48.11.1.2." ,
      "48.11.1.2.2.2.2.1.",
      "48.11.1.2.2.2.2.2.",
      "48.11.1.2.2.3.",
      "48.11.2.",
      "48.11.2.1.",
      "48.11.2.1.1.",
      "48.11.3.",
      "48.11.3.3.3.1.",
      "50."
    ))