添加" ' "围绕公式/字符串中的任意数量的函数

时间:2017-05-03 15:04:29

标签: r string formula

简单请求:

我想要采用类似于以下内容的公式/字符串:

"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(差异(___), - _____:____)"在一个字符串中。

背景:

这样我就可以使用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?

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

请注意,我们并不真的想要替换所有函数调用,因为+是一个函数(甚至可以将~视为一个函数)但我们只想更换某些函数那些。假设我们要处理的唯一函数调用是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)`

<强> ADDED

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

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

答案 1 :(得分:2)

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

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 = " + "))