字符串操作 - 用变量替换文本并解析

时间:2018-03-28 09:06:56

标签: r regex string csv

任务:

我有一个任务在csv输入数据上应用一些给定的计算规则。 在第一步,我需要"翻译"给出了R语言的规则(例子如下)。在第二步中,我将一些csv文件(表格)加载到R中,并将规则应用于数据,以检查规则中给出的条件是否可以得到确认。

C 01.00,F 08.01.b等是不同的表格。 每张纸都有很多行和列。

我的想法是为每张纸定义一张Matrix。例如,F0801b是表格中的矩阵" F 08.01.b" 99行99列,其中包含许多值。变量F0801bR450将是F0801b-Matrix的第45行。

规则可能如下所示:

{r390, c010} == {r400, c010} + {r410, c010} + {r420, c010}

每个计算规则都连接到特定的"表"。如果规则如上所述,则第39行的单元格和同一张纸张的第1列必须等于右侧的术语。 任务是从计算规则中给出的单元格中获取值,因此将{}中的字符串替换为Matrix中的值,并在最后解析方程式以检查条件是否为真。

{F 19.00.a, c100} <= {F 18.00.a, c120}

我们说这条规则属于F 17.00.a表。这里,调用其他表格的(总和)列并进行比较。

{C 02.00, r570 , c010} == {C 23.00, r010 , c070}

此处,应比较其他形式的特定细胞。

{C 01.00, r480} * ({C 04.00, r230} + {C 04.00, r300} + {C 04.00, r370}) == -(max({C 04.00, r230} + {C 04.00, r300} + {C 04.00, r370} - {C 04.00, r190}, 0)) * {C 04.00, r230}

在此示例中,应计算不同表格的行和列,以检查条件是否为真。

{F 08.01.b, r450} == sum({F 08.01.a, ({r010}, {r020}, {r050}, {r360}, {r440})})

规则的外观的另一个例子。

挑战:

再次说明:这里的挑战是将这些字符串翻译成R语言并将规则应用于数据。目标是拥有一个具有逻辑值作为输出的自动化。

到目前为止我尝试过的事情:

用特定值替换单元格坐标:

string<-"{r390, c010} == {r400, c010} + {r410, c010} + {r420, c010}"
# the string is actually a row of a data.frame-column like vrList$Formula[i]   
pat  <- "\\d+(?>\\d)\\B"
pat2 <- "\\{r..., c...\\}"

getCell=function(data,string){
  pos=regmatches(string,gregexpr(pat,string,perl = T))
  data[do.call(rbind,lapply(pos,as.numeric))]
}

pos<- regmatches(string,gregexpr(pat2,string,perl = T))
getCell(table,unlist(pos)) 

上面的代码可以从我的Matrix的单元格中获取值,其中包含随机生成的数字,以证明代码的机制。为每个工作表存储多个变量并从不同矩阵中获取值的想法是新的,尚未实现。

b <- gsubfn(pat2, getCell, string); b

这里我想用值替换原始字符串,但gsubfn在这里确实没有用。最后,下面的解析应该是以下部分:

eval(parse(text=b))

我希望这些例子足以显示任务的复杂性。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

你真的需要自定义公式吗?有没有理由不写一个R表达式,如:

M <- matrix(1:16, 4) # test matrix

M[1, 2] == M[4, 1] + M[3, 3] + M[2, 1]
## [1] FALSE

如果您确实需要自定义公式表示法,那么问题中的公式似乎不一致,因此不清楚使用哪个,但如果公式为以下形式,则为gsub / parse / eval会这样做:

 # test input
 matrix_name <- "M"
 string <- "{r001, c002} == {r004, c001} + {r003, c003} + {r002, c002}"

 txt <- gsub("\\{r(\\d+), c(\\d+)\\}", paste0(matrix_name, "[\\1, \\2]"), string)
 eval(parse(text = txt))
 ## [1] FALSE

或如果公式为

形式
 string2 <- "{M r001, c002} == {M r004, c001} + {M r003, c003} + {M r002, c002}" # input

 txt2 <- gsub("\\{(\\w+) r(\\d+), c(\\d+)\\}", "\\1[\\2, \\3]", string2)
 eval(parse(text = txt2))
 ## [1] FALSE

您之前的另一个变体问题已经回答:R: Define ranges from text using regex