【问题标题】:Coercing String to Vector将字符串强制转换为向量
【发布时间】:2018-04-26 05:57:09
【问题描述】:

我正在尝试创建一个计算器,它将以循环形式编写的排列组相乘(此过程在这篇文章中进行了描述,对于不熟悉的任何人:https://math.stackexchange.com/questions/31763/multiplication-in-permutation-groups-written-in-cyclic-notation)。虽然我知道使用 Python 或其他东西会更容易做到这一点,但我想练习用 R 编写代码,因为它对我来说相对较新。

我的游戏计划是输入一个输入,例如“(1 2 3)(2 4 1)”,并将其拆分为两个单独的列表或向量。但是,我在开始这个时遇到了麻烦,因为根据我对字符函数的理解(我在这里研究过:https://www.statmethods.net/management/functions.html),我最终将不得不使用函数 grep() 来找到我的字符串中出现 ")(" 的点从那里拆分。但是,grep 仅将向量作为其参数,因此我试图将我的字符串强制转换为向量。在研究这个问题时,我大多看到人们建议使用 as.integer(unlist(str_split())) ,但是,这对我不起作用,因为当我拆分时,并非所有内容都是整数并且值变为 NA,如本例所示。

    library(tidyverse)
    x <- "(1 2 3)(2 4 1)"
    x <- as.integer(unlist(str_split(x," ")))'
    x

当不只是涉及整数时,是否有另一种方法可以将字符串转换为向量?我也意识到我试图拆分两个排列的方法非常迂回,但那是因为我研究的字符函数似乎是唯一的方法。如果有其他功能可以让这更容易,请告诉我。

谢谢!

【问题讨论】:

  • "(1 2 3)(2 4 1)" 是一个一元向量,你可以像现在这样调用grep
  • 感谢您的回复!当我使用 grep 作为 1 元素向量时,当我搜索我正在寻找的表达式“)(”时它只输出 1,所以它对我来说不是很有用,因为我试图确定这一点在哪里。
  • 您应该阅读grep 的文档,它可能不会像您认为的那样做。我认为与您尝试做的最接近的基本 R 匹配是 regexpr("\\)\\(", x)
  • 我强烈建议重新考虑您的意见。如果你把c(1, 2, 3) %cyc% c(2, 4, 1)作为输入,你只需要定义一个`%cyc%`函数进行实际操作,不需要解析任何字符串。

标签: r


【解决方案1】:

代码中的注释。

x <- "(1 2 3)(2 4 1)"

out1 <- strsplit(x, split = ")(", fixed = TRUE)[[1]] # split on close and open bracket
out2 <- gsub("[\\(|\\)]", replacement = "", out1) # remove brackets
out3 <- strsplit(out2, " ") # tease out numbers between spaces
lapply(out3, as.integer)

[[1]]
[1] 1 2 3

[[2]]
[1] 2 4 1

【讨论】:

    【解决方案2】:

    R 上实际上没有任何标量。1TRUE"a" 等单个值都是 1 元素向量。 grep(pattern, x) 可以在您的原始字符串上正常工作。作为实现理想目标的起点,我建议使用以下方法拆分组:

    > str_extract_all(x, "\\([0-9 ]+\\)")
    [[1]]
    [1] "(1 2 3)" "(2 4 1)"
    

    【讨论】:

    • 感谢您提供此代码!我不熟悉 str_extract_all 函数。
    【解决方案3】:

    如果我们需要用括号分割字符串

    strsplit(x, "(?<=\\))(?=\\()", perl = TRUE)[[1]]
    #[1] "(1 2 3)" "(2 4 1)"
    

    或者我们可以使用来自qdapRegex的便捷包装器

    library(qdapRegex)
    ex_round(x, include.marker = TRUE)[[1]]
    #[1] "(1 2 3)" "(2 4 1)"
    

    【讨论】:

      【解决方案4】:

      替代方案:使用library(magrittr)

      x <- "(1 2 3)(2 4 1)" 
      
      x %>%
      gsub("^\\(","c(",.) %>% gsub("\\)\\(","),c(",.) %>% gsub("(?=\\s\\d)",", ",.,perl=T) %>%
          paste0("list(",.,")") %>% {eval(parse(text=.))}
      

      结果:

      # [[1]]
      # [1] 1 2 3
      # 
      # [[2]]
      # [1] 2 4 1
      

      【讨论】:

        【解决方案5】:

        您可以将chartrread.table 一起使用:

        read.table(text= chartr("()"," \n",x))
        #   V1 V2 V3
        # 1  1  2  3
        # 2  2  4  1
        

        【讨论】:

          猜你喜欢
          • 2014-04-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-03-02
          • 1970-01-01
          • 2016-05-03
          • 1970-01-01
          相关资源
          最近更新 更多