简体   繁体   中英

Coercing String to Vector

I'm trying to create a calculator that multiplies permutation groups written in cyclic form (the process of which is described in this post, for anyone unfamiliar: https://math.stackexchange.com/questions/31763/multiplication-in-permutation-groups-written-in-cyclic-notation ). Although I know this would be easier to do with Python or something else, I wanted to practice writing code in R since it is relatively new to me.

My gameplan for this is take an input, such as "(1 2 3)(2 4 1)" and split it into two separate lists or vectors. However, I am having trouble starting this because from my understanding of character functions (which I researched here: https://www.statmethods.net/management/functions.html ) I will ultimately have to use the function grep() to find the points where ")(" occur in my string to split from there. However, grep only takes vectors for its argument, so I am trying to coerce my string into a vector. In researching this problem, I have mostly seen people suggest to use as.integer(unlist(str_split())), however, this doesn't work for me as when I split, not everything is an integer and the values become NA, as seen in this example.

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

Is there an alternative way to turn a string into a vector when there are not just integers involved? I also realize that the means by which I am trying to split up the two permutations is very roundabout, but that is because of the character functions that I researched this seems like the only way. If there are other functions that would make this easier, please let me know.

Thank you!

Comments in the code.

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

There aren't really any scalars on R. Single values like 1 , TRUE , and "a" are all 1-element vectors. grep(pattern, x) will work fine on your original string. As a starting point for getting towards your desired goal, I would suggest splitting the groups using:

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

If we need to split the strings with the brackets

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

Or we can use convenient wrapper from qdapRegex

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

alternative: using library(magrittr)

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

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

result:

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

You could use chartr with read.table :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM