在 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)))
简单请求:
我想 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)))