在 formula/string 中的任意数量的函数周围添加一个“'”

Add a " ' " around any number of functions in a formula/string

简单请求:

我想 formulas/strings 类似于以下内容:

"A ~ 1 + B + C + L(diff(B), -k:k) + L(diff(C), -k:k)"

并将它们更改为将函数视为字符,如下所示:

"A ~ 1 + B + C + `L(diff(B), -k:k)` + `L(diff(C), -k:k)`"

一个字符串中可以有任意数量的"L(diff(___), -____:____)"。

背景:

这样我就可以使用 dynlm 制作的输出模型,运行 它们具有仅依赖 "lm" 对象的函数。

# package
library(dynlm)
# data
A <- as.ts(rnorm(20, 10, 2))
B <- as.ts(A + rnorm(20, 6, 2))
C <- as.ts(rnorm(20, 3, 1))
# lags/leads
k <- 1

# dynlm model
dyn.mod <- dynlm(A ~ 1 + B + C + L(diff(B), -k:k) + L(diff(C), -k:k))

# capture the formula and data
dyn.mod.call <- gsub("    ", "", paste(deparse(dyn.mod$call$formula), collapse = "")) # just in case formula is too long
dyn.mod.model <- dyn.mod$model # the matrix that was created from  the call formula

# Do the following
lm(dyn.mod.call, data = dyn.mod.model) # Will not run obviously, 
lm(A ~ 1 + B + C + `L(diff(B), -k:k)` + `L(diff(C), -k:k)`, data = dyn.mod.model) # will run 

# how do I change
dyn.mod.call
# [1] "A ~ 1 + B + C + L(diff(B), -k:k) + L(diff(C), -k:k)"

# to ad " ` " around each dynlm "L()" function so the process is not manual?

感谢您的帮助。

您可以使用字符串操作来更改公式。

x <- deparse(A ~ 1 + B + C + L(diff(B), -k:k) + L(diff(C), -k:k))
parts <- unlist(strsplit(x, " \+ "))
parts <- c(parts[1:3], paste0("`", parts[4:5], "`"))
as.formula(paste(parts, collapse = " + "))

请注意,我们并不是真的想替换所有函数调用,因为 + 是一个函数(甚至 ~ 也可以看作是一个函数),但我们只想替换某些那些。假设我们要处理的唯一函数调用是 L。根据要匹配的内容适当修改第二个if。显示的函数递归工作。没有使用包。

enquote_L <- function(x) {
    if (length(x) == 1) return(x)
    if (x[[1]] == as.name("L")) return(as.name(format(x)))
    replace(x, -1, lapply(x[-1], enquote_L))
  }

s <- "A ~ 1 + B + C + L(diff(B), -k:k) + L(diff(C), -k:k)"
enquote_L(as.formula(s))
## A ~ 1 + B + C + `L(diff(B), -k:k)` + `L(diff(C), -k:k)`

已添加

如果有多种函数,而 +~ 是唯一不被处理的函数,那么一个变体可能是将第二个 if 替换为:

if (x[[1]] != as.name("+") && x[[1]] != as.name("~")) return(as.name(format(x)))