在R函数体中搜索特定行

  • 本文关键字:搜索 函数体 r
  • 更新时间 :
  • 英文 :


我希望"复制和修改";身体某一特定部位的功能。目前,我有

nearest_psd <- function(mat) {
ed <- eigen(mat)
eigvecs <- ed$vectors
eigvals <- ed$values
eigvals[eigvals<0] <- 0

eigvecs %*% diag(eigvals) %*% t(eigvecs)
}
nearest_pd <- nearest_psd
formals(nearest_pd)$pdeps <- 1e-08
body(nearest_pd)[[c(7,3)]] <- quote(pdeps)

,使得除了线eigvals[eigvals<0] <- pdeps之外,nearest_pdnearest_psd的副本。

然而,行号(在这种情况下是7(是硬编码的,我更希望有一种稳健的方法来确定这个行号。如何搜索包含表达式eigvals[eigvals<0] <- 0的行?

您可以使用identical来比较两个表达式;这样,您就可以识别并替换有问题的表达式:

to_replace = vapply(body(nearest_pd), function (e) identical(e, quote(eigvals[eigvals < 0] <- 0)), logical(1L))
body(nearest_pd)[to_replace] = list(quote(eigvals[eigvals < pdeps] <- pdeps))

然而,这并不比您的代码更可读,也不更健壮:在这两种情况下,您都被迫对相关信息进行硬编码;在您的代码中,索引。在我的表达中。出于这个原因,我不建议使用这个。

…当然,您可以使用AST walker将函数体中出现的所有0替换为pdeps。但这样更好吗?不能,因为0可以用于其他目的。它目前不是,但谁知道呢,一旦原始函数发生变化。如果不能假设原始函数发生变化,为什么不对新函数进行完全的硬编码呢?也就是说,写这个:

nearest_pd <- function (mat, pdeps = 1e-08) {
ed <- eigen(mat)
eigvecs <- ed$vectors
eigvals <- ed$values
eigvals[eigvals < pdeps] <- pdeps
eigvecs %*% diag(eigvals) %*% t(eigvecs)
}

…不需要仅仅为了元编程而使用元编程。

以下内容可以满足您的需要。

nearest_psd <- function(mat) {

ed <- eigen(mat)
eigvecs <- ed$vectors
eigvals <- ed$values
eigvals[eigvals<0] <- 0

eigvecs %*% diag(eigvals) %*% t(eigvecs)
}

nearest_pd <- nearest_psd
formals(nearest_pd)$pdeps <- 1e-08

nearest_psd_body <- body(nearest_psd)

# Find the string we a re looking for and replace it ...
new.code <- gsub("eigvals[eigvals < 0] <- 0",
"MY_NEW_CODE",
nearest_psd_body, fixed = TRUE)
# Buidling the function body as a string.
new.code <- new.code[-1] # delete first { such that ...
new.code <- paste(new.code, collapse = ";") # we can collapse the remaining here ....
new.code <- paste("{", new.code, "}", sep = "", collapse = "") # and then wrap the remaining in { }
# parse returns an expression.
body(nearest_pd) <- parse(text = new.code)

请参阅在基本级别上,eval解析在R中做什么?用于CCD_ 9的外植体。或者在编程中,什么是表达式?什么是表达。

最新更新