任务:
我有一个任务在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))
我希望这些例子足以显示任务的复杂性。
感谢您的帮助。
答案 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