代码之家  ›  专栏  ›  技术社区  ›  Joe

将数据中的最后一个和倒数第二个数字加1

r
  •  1
  • Joe  · 技术社区  · 4 月前

    我有以下数据,我试图将其作为1除以数字的最后一部分 - 我的数据如下:;

    dat
    "4-3" "60-0 2-5" "10-1 3-2" "20-2 3-0" "3-0" "20-5 3-0"
    

    我试图归档的是,在这里,我们分别在最后一个数字上加1,在倒数第二个数字上加1;

    dat1
    "5-3" "60-0 3-5" "10-1 4-2" "20-2 4-0" "4-0" "20-5 4-0"
    
    dat2
    "4-4" "60-0 2-6" "10-1 3-3" "20-2 3-1" "3-1" "20-5 3-1"
    

    我认为可以使用gsub()分割数据,尽管这可能很棘手,因为我的数据长度在1组数字和2之间变化,但我的另一个问题是,如果我使用gsub,我就无法添加(据我所知)。我的理论类似于识别最后一个数字并加1,然后识别倒数第二个数字并加1

    2 回复  |  直到 4 月前
        1
  •  3
  •   G. Grothendieck    4 月前

    gsubfn 就像 gsub 除了替换参数可以是函数,并且如这里所示,它可以选择使用紧凑的公式符号表示。正则表达式中的捕获组被传递给函数,主体中的自由变量按出现顺序分配给它们。然后,函数的输出将替换正则表达式匹配的部分。

    library(gsubfn)
    
    res1 <- gsubfn("(\\d+)(-\\d+)$", ~ paste0(as.numeric(x) + 1, y), dat)
    identical(res1, dat1)
    ## [1] TRUE
    
    res2 <- gsubfn("(\\d+)$", ~ as.numeric(x) + 1, dat)
    identical(res2, dat2)
    ## [1] TRUE
    

    注:

    dat <- c("4-3", "60-0 2-5", "10-1 3-2", "20-2 3-0", "3-0", "20-5 3-0")
    dat1 <- c("5-3", "60-0 3-5", "10-1 4-2", "20-2 4-0", "4-0", "20-5 4-0")
    dat2 <- c("4-4", "60-0 2-6", "10-1 3-3", "20-2 3-1", "3-1", "20-5 3-1")
    
        2
  •  2
  •   Tim G    4 月前

    我们可以 paste0 我们的新字符串使用一个函数,该函数在字符串中查找长度为n的字符,并添加一个 1 这是我能找到的最严密的方式,尽管我在写作时几乎崩溃了。

    # Function to add 1 to the nchar(string)-n char in string
    add_to_last <- function(x, n=0) { paste0(substr(x, 1, nchar(x) - 1-n), as.numeric(substr(x, nchar(x)-n, nchar(x)-n))+1, substr(x, nchar(x) -n+1, nchar(x)))}
    
    dat <- c("4-3", "60-0 2-5", "10-1 3-2", "20-2 3-0", "3-0", "20-5 3-0")  
    
    # Sapply 
    > sapply(dat, add_to_last)
           4-3   60-0 2-5   10-1 3-2   20-2 3-0        3-0   20-5 3-0 
         "4-4" "60-0 2-6" "10-1 3-3" "20-2 3-1"      "3-1" "20-5 3-1" 
    > sapply(dat, add_to_last, n=2)
           4-3   60-0 2-5   10-1 3-2   20-2 3-0        3-0   20-5 3-0 
         "5-3" "60-0 3-5" "10-1 4-2" "20-2 4-0"      "4-0" "20-5 4-0" 
    
        3
  •  0
  •   ThomasIsCoding    4 月前

    您可以使用 sub + paste0 如下图所示

    dat1 <- paste0(
      sub("\\d+-\\d+$", "", dat),
      as.integer(sub(".*(\\d+)-.*$", "\\1", dat)) + 1,
      sub(".*(-\\d+)$", "\\1", dat)
    )
    
    dat2 <- paste0(
      sub("\\d+$", "", dat),
      as.integer(sub(".*-", "", dat)) + 1
    )
    

    这样

    > dat1
    [1] "5-3"      "60-0 3-5" "10-1 4-2" "20-2 4-0" "4-0"      "20-5 4-0"
    
    > dat2
    [1] "4-4"      "60-0 2-6" "10-1 3-3" "20-2 3-1" "3-1"      "20-5 3-1"