R 中“公式”与“data.table”的意外行为

问题描述 投票:0回答:2

我正在尝试动态形成一个公式以在

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
也是如此。

我想了解正在发生的事情并避免它。

r function data.table
2个回答
0
投票

也许你想添加一个

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
不喜欢回收,所以在这个例子中需要它。


0
投票

这只是由于 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>
# ....
© www.soinside.com 2019 - 2024. All rights reserved.