我正在尝试动态形成一个公式以在
dynlm
中使用。我遇到了一个我不明白的function
行为,从这段代码可以看出:
library(data.table)
dt_test <- data.table("a"=rnorm(10), "b"=1:5)
dt_test[, .(.(
formula("z_val ~ s_val + q_val + L(s_dval, 32:0) + L(q_dval, 2:0) + 1 + tt + tt2")
)), .(b)]
上面的代码预计会为
b
的每个值生成(相同的)公式。该公式包含在 .(.(...))
中以返回一个列表,以便它可以正确存储在原始 data.table 的列中。
但是,返回的公式与最初提供的字符串不匹配,而是在
+
和 tt
之间添加了一个逗号,从输出中可以看到:
b V1
<int> <list>
1: 1 z_val ~ s_val + q_val + L(s_dval, 32:0) + L(q_dval, 2:0) + 1 + , tt + tt2
2: 2 z_val ~ s_val + q_val + L(s_dval, 32:0) + L(q_dval, 2:0) + 1 + , tt + tt2
3: 3 z_val ~ s_val + q_val + L(s_dval, 32:0) + L(q_dval, 2:0) + 1 + , tt + tt2
4: 4 z_val ~ s_val + q_val + L(s_dval, 32:0) + L(q_dval, 2:0) + 1 + , tt + tt2
5: 5 z_val ~ s_val + q_val + L(s_dval, 32:0) + L(q_dval, 2:0) + 1 + , tt + tt2
本质上,它在没有逗号的地方添加了一个逗号。它甚至会重新排列总和的项,但如果我删除
q_val
,它就会停止这样做。 as.formula
也是如此。
我想了解正在发生的事情并避免它。
也许你想添加一个
list
列,像这样:
> library(data.table)
> dt_test <- data.table("a"=rnorm(10), "b"=1:5)
> dt_test[, x := list(rep(list(as.formula("z_val ~ s_val + q_val + L(s_dval, 32:0) + L(q_dval, 2:0) + 1 + tt + tt2")), .N))]
> dt_test$x[[1]]
z_val ~ s_val + q_val + L(s_dval, 32:0) + L(q_dval, 2:0) + 1 +
tt + tt2
<environment: 0x56169e0ce3c8>
打印时这看起来很奇怪,
> dt_test |> head(2)
a b x
<num> <int> <list>
1: -0.5439367 1 z_val ~ s_val + q_val + L(s_dval, 32:0) + L(q_dval, 2:0) + 1 + , tt + tt2
2: 0.1078461 2 z_val ~ s_val + q_val + L(s_dval, 32:0) + L(q_dval, 2:0) + 1 + , tt + tt2
但实际上是一个公式:
> class(dt_test$x[[1]])
[1] "formula"
您可以将其适应您动态的
.(b)
内容。不确定您是否需要rep
; data.table
不喜欢回收,所以在这个例子中需要它。
这只是由于 R 处理长公式的方式而导致的外观打印问题:
如果你跑步:
formula(paste0("z_val ~ s_val + q_val + L(s_dval, 32:0) + L(q_dval, 2:0) + 1 + tt + tt2"))
您将看到 R 将默认将其打印为 2 行,并在“tt + tt2”处将其切断:
#z_val ~ s_val + q_val + L(s_dval, 32:0) + L(q_dval, 2:0) + 1 +
# tt + tt2
这对于 R 向您展示公式的方式有点意义 - 如果您运行
deparse
,它将输出大小为 2 的字符向量:
[1] "z_val ~ s_val + q_val + L(s_dval, 32:0) + L(q_dval, 2:0) + 1 + "
[2] " tt + tt2"
但是,将原始代码保存为
df_formulas
,您会看到它正常存储公式:
df_formulas <- dt_test[, .(.(
formula("z_val ~ s_val + q_val + L(s_dval, 32:0) + L(q_dval, 2:0) + 1 + tt + tt2")
)), .(b)]
dt_formulas[[2]]
# [[1]]
# z_val ~ s_val + q_val + L(s_dval, 32:0) + L(q_dval, 2:0) + 1 +
# tt + tt2
# <environment: 0x7fa96ff6ffd8>
#
# [[2]]
# z_val ~ s_val + q_val + L(s_dval, 32:0) + L(q_dval, 2:0) + 1 +
# tt + tt2
# <environment: 0x7fa96ff6ffd8>
# ....