方程组.如何拆分字符串以获得R中的两个矩阵A和b

Kam*_*mil 3 regex r

我有一个像这样的字符串(变量和常量的数量并不重要):

> my_string <- "-x+2y+z=-1; x-3y-2z=-1; 3x-y-z=4"
Run Code Online (Sandbox Code Playgroud)

我知道如何cbind(A, b)使用替换和数字函数获取矩阵...

#    [,1]   [,2]   [,3]    [,4]
# [1,] -1     2      1      -1
# [2,]  1    -3     -2      -1
# [3,]  3    -1     -1       4
Run Code Online (Sandbox Code Playgroud)

......但不知道如何自动获得两个矩阵Ab

A
#    [,1]   [,2]   [,3]
# [1,]-1     2      1
# [2,] 1    -3     -2 
# [3,] 3    -1     -1  

b
#    [,1]   
# [1,]-1
# [2,]-1
# [3,] 4 
Run Code Online (Sandbox Code Playgroud)

这意味着我如何分割这个字符串=以获得一个矩阵,其中数字元素位于等号前面,另一个矩阵元素位于它之后?

编辑.到目前为止我做了这个:

my_string<-"-x+2y+z=-1; x-3y-2z=-1; 3x-y-z=4"    
my_string<-gsub('([[:punct:]]|\\s)([a-z])', '\\11\\2', my_string)   
my_string<-stringr::str_replace_all(my_string,"[a-z]"," ")    
my_string<-stringr::str_replace_all(my_string,"; ",";")    
my_string<-stringr::str_replace_all(my_string,"[-]","+-")       
my_string<-stringr::str_replace_all(my_string,"[+]"," ")    
my_string<-stringr::str_replace_all(my_string,"[=] ","=")    
my_string<-stringr::str_replace_all(my_string,"   ",",")    
my_string<-stringr::str_replace_all(my_string,"  ",",")    
my_string<-stringr::str_replace_all(my_string," ",",")    
my_string<-gsub("^,","",my_string)        
my_string <- strsplit(my_string, "=|;")   
Run Code Online (Sandbox Code Playgroud)

我获得了:

# "-1,2,1"  "-1"      "1,-3,-2" "-1"      "3,-1,-1" "4"  
Run Code Online (Sandbox Code Playgroud)

如何连接这个字符串?

> A <- "-1,2,1,1,-3,-2,3,-1,-1"
> b <- "-1,-1,4"
Run Code Online (Sandbox Code Playgroud)

G. *_*eck 6

这是一些替代方案.所有都可以处理my_string问题所示的字符串,但(3),(4)和(5)也可以处理一些变量缺失且变量乱序的方程式.只有(4)硬编码变量名,但它在(5)中概括.

1)在没有数字乘数给定的任何变量之前插入1 s1.然后提取变量名称,假设它们在每个字母上,并计算给出数字的唯一变量名称n.然后提取数字,将它们转换为数字并使用它们将它们整形为矩阵n.假设所有三个变量都存在于每个等式中,并且它们的顺序相同,因为问题的例子就是这种情况.

library(gsubfn)

my_string<-"-x+2y+z=-1; x-3y-2z=-1; 3x-y-z=4"
s1 <- gsub('(^|\\W)([a-z])', '\\11\\2', my_string) # from your prior question

n <- length(strapplyc(s1, "[a-z]", simplify = unique))
matrix(strapply(s1, "(-?\\d+)", as.numeric, simplify = c), n, byrow = TRUE)
Run Code Online (Sandbox Code Playgroud)

赠送:

     [,1] [,2] [,3] [,4]
[1,]   -1    2    1   -1
[2,]    1   -3   -2   -1
[3,]    3   -1   -1    4
Run Code Online (Sandbox Code Playgroud)

2)变体是以s1分号给出从上面分开s2.然后strapply用来挑选给出的数字mat.最后将数字从字符转换为数字.

library(gsubfn)

s2 <- strsplit(s1, ";")

mat <- do.call("rbind", sapply(s2, strapply, "(-?\\d+)"))
matrix(as.numeric(mat), nrow(mat))
Run Code Online (Sandbox Code Playgroud)

赠送:

     [,1] [,2] [,3] [,4]
[1,]   -1    2    1   -1
[2,]    1   -3   -2   -1
[3,]    3   -1   -1    4
Run Code Online (Sandbox Code Playgroud)

3)这个替代方案可以处理缺失的变量,例如下面的例子y中第一个等式中缺少的变量. varnames是变量名称.该extr函数采用变量名称并提取其系数,如果未出现变量则为0.

library(gsubfn)

my_string2 <- "-x+z=-1; x-3y-2z=-1; 3x-y-z=4"
s1 <- gsub('(^|\\W)([a-z])', '\\11\\2', my_string2)
s2 <- strsplit(s1, ";")

varnames <- sort(strapplyc(s1, "[a-z]", simplify = unique))
extr <- function(x) 
  strapply(s2[[1]], paste0("-?\\d", x), ~ as.numeric(gsub("\\D", "", x)), empty = 0)
A <- sapply(varnames, extr)
b <- as.numeric(sub(".*=", "", s2[[1]]))
Run Code Online (Sandbox Code Playgroud)

赠送:

> A
     x y z
[1,] 1 0 1
[2,] 1 3 2
[3,] 3 1 1
> b
[1] -1 -1  4
Run Code Online (Sandbox Code Playgroud)

4)这一个替换x*c(1, 0, 0),y*c(0,1,0)z*c(0,0,1)和评估它们产生A.它特别简单.它还可以处理并非所有变量都存在的方程式.它假设变量x,y并且z虽然它可以推广.

my_string2 <- "-x+z=-1; x-3y-2z=-1; 3x-y-z=4"
s1 <- gsub('(^|\\W)([a-z])', '\\11\\2', my_string2)
s2 <- strsplit(s1, ";")
s <- sub("=.*", "", s2[[1]])
s <- gsub("x", "*c(1, 0, 0)", s)
s <- gsub("y", "*c(0, 1, 0)", s)
s <- gsub("z", "*c(0, 0, 1)", s)
A <- eval(parse(text = paste("rbind(", paste(s, collapse = ","), ")")))
b <- as.numeric(sub(".*=", "", s2[[1]]))
Run Code Online (Sandbox Code Playgroud)

赠送:

> A
     [,1] [,2] [,3]
[1,]   -1    0    1
[2,]    1   -3   -2
[3,]    3   -1   -1
> b
[1] -1 -1  4
Run Code Online (Sandbox Code Playgroud)

5)这是(4)的通用版本,其中x,y和z不是硬编码的.它可以处理无序和缺失的变量.我们首先获取变量名称varnames,分割输入字符串给出spl,对于第i个变量名称,用0的向量替换它,在第i个位置给出1 ss1,*在任何这样的向量之前插入前缀为数字给出ss2,删除=以及之后的所有内容并将其包围cbind(...)并评估为R表达式A. b=转换为数字后的所有内容.

library(gsubfn)
my_string2 <- "-z+x=-1; x-3y-2z=-1; 3x-y-z=4"
ss0 <- my_string2
varnames <- sort(strapplyc(ss0, "[a-z]", simplify = unique))
spl <- strsplit(ss0, ";")[[1]]
ss1 <- gsubfn("[a-z]", x ~ (match(x, varnames) == seq_along(varnames))+0, spl)
ss2 <- gsub("(\\d)c", "\\1*c", ss1)
ss3 <- sub("=.*", "", ss2)
A <- eval(parse(text = paste("rbind(", paste(ss3, collapse = ","), ")")))
b <- as.numeric(sub(".*=", "", ss2))
Run Code Online (Sandbox Code Playgroud)

赠送:

> A
     [,1] [,2] [,3]
[1,]    1    0   -1
[2,]    1   -3   -2
[3,]    3   -1   -1
> b
[1] -1 -1  4
Run Code Online (Sandbox Code Playgroud)