【问题标题】:String manipulation - replace text by variable and parse字符串操作 - 用变量替换文本并解析
【发布时间】:2018-03-28 09:06:55
【问题描述】:

任务:

我有一个任务来对 csv 输入数据应用一些给定的计算规则。 在第一步中,我需要将给定的规则(下面的示例)“翻译”为 R 语言。在第二步中,我将一些csv文件(Sheets)加载到R中并将规则应用于数据以检查规则中给出的条件是否可以确认。

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

想法:

我的想法是为每张纸定义一个矩阵。例如F0801b 是来自工作表“F 08.01.b”的矩阵,其中包含 99 行和 99 列以及许多值。变量F0801bR450 将是 F0801b 矩阵的第 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}

本例中,不同Sheet的行和列都要计算,判断条件是否成立。

{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)) 

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

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

在这里,我想用值替换原始字符串,但 gsubfn 在这里并不起作用。最后,下面的解析应该做 ist 部分:

eval(parse(text=b))

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

感谢您的帮助。

【问题讨论】:

标签: r regex string csv


【解决方案1】:

您真的需要自定义公式吗?有什么理由不只写一个 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-22
    • 2014-10-29
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    相关资源
    最近更新 更多