如何使用更新将前缀添加到公式的右侧?
How do I add a prefix to the right hand side of a Formula using update?
假设我有一个 Formula
的列表:
library(Formula)
models <- list(y ~ x1, y ~ x2, y ~ x3)
models <- lapply(models, as.Formula)
并说我想将它们更新为 y ~ 1 | x1 | 1
、y ~ 1 | x2 | 1
和 y ~ 1 | x3 | 1
(例如,使用 mnlogit
)。如果我将 update
与 lapply
一起使用,我可以将 | 1
添加到末尾:
lapply(models, update, . ~ . | 1) # Works as expected
# [[1]]
# y ~ x1 | 1
#
# [[2]]
# y ~ x2 | 1
#
# [[3]]
# y ~ x3 | 1
但是我无法在开头添加 1 |
:
lapply(models, update, . ~ 1 | . | 1) # Fails -- why is the dot not replaced?
# [[1]]
# y ~ 1 | . | 1
#
# [[2]]
# y ~ 1 | . | 1
#
# [[3]]
# y ~ 1 | . | 1
有谁知道这是为什么,或者如何修复它(当然,除了一个一个地修复每个模型)?
就个人而言,当我遇到一个简单的问题时,我总是利用字符串。这是在 base-R 中:
lapply(models, function(x) {
as.formula(paste( 'y ~ 1 | ', labels(terms(x)) , '| 1')))
}
输出为:
[[1]]
y ~ 1 | x1 | 1
<environment: 0x000000000a475128>
[[2]]
y ~ 1 | x2 | 1
<environment: 0x00000000003ea848>
[[3]]
y ~ 1 | x3 | 1
<environment: 0x000000000a94e100>
你需要的所有公式。
如果 mnlogit
接受公式参数中的字符串(即像 lm
那样在内部将任何公式字符串转换为公式类型),那么您甚至不需要 as.formula
位以上 lapply
.
至于主要问题:如何设置公式?
我建议先添加两个额外的拦截部分,然后重新排序右侧:
f <- y ~ x2
ff <- update(Formula(f), . ~ . | 1 | 1)
formula(ff, rhs = c(2, 1, 3))
## y ~ 1 | x2 | 1
然后是关于:为什么更新只适用于 .在第一部分?
您期望此代码 returns 相同的结果:
f <- y ~ x2
update(Formula(f), . ~ 1 | . | 1)
## y ~ 1 | . | 1
但显然不是。原因很简单:update()
方法循环遍历所有左手和右手部分。此处,第一个右侧部分 x2
更新为 1
。第二个右侧部分是空的(f
只有一个右侧)因此更新为 .
。同理,对于第三部分。
如果原始公式中恰好有一个右侧,则可以实现您的方法。但是对于几个部分,这将是一团糟。例如,
update(Formula(y ~ x1 | x2 | x3), . ~ . + z1 | 1 | . - x3)
## y ~ x1 + z1 | 1 | 1
假设我有一个 Formula
的列表:
library(Formula)
models <- list(y ~ x1, y ~ x2, y ~ x3)
models <- lapply(models, as.Formula)
并说我想将它们更新为 y ~ 1 | x1 | 1
、y ~ 1 | x2 | 1
和 y ~ 1 | x3 | 1
(例如,使用 mnlogit
)。如果我将 update
与 lapply
一起使用,我可以将 | 1
添加到末尾:
lapply(models, update, . ~ . | 1) # Works as expected
# [[1]]
# y ~ x1 | 1
#
# [[2]]
# y ~ x2 | 1
#
# [[3]]
# y ~ x3 | 1
但是我无法在开头添加 1 |
:
lapply(models, update, . ~ 1 | . | 1) # Fails -- why is the dot not replaced?
# [[1]]
# y ~ 1 | . | 1
#
# [[2]]
# y ~ 1 | . | 1
#
# [[3]]
# y ~ 1 | . | 1
有谁知道这是为什么,或者如何修复它(当然,除了一个一个地修复每个模型)?
就个人而言,当我遇到一个简单的问题时,我总是利用字符串。这是在 base-R 中:
lapply(models, function(x) {
as.formula(paste( 'y ~ 1 | ', labels(terms(x)) , '| 1')))
}
输出为:
[[1]]
y ~ 1 | x1 | 1
<environment: 0x000000000a475128>
[[2]]
y ~ 1 | x2 | 1
<environment: 0x00000000003ea848>
[[3]]
y ~ 1 | x3 | 1
<environment: 0x000000000a94e100>
你需要的所有公式。
如果 mnlogit
接受公式参数中的字符串(即像 lm
那样在内部将任何公式字符串转换为公式类型),那么您甚至不需要 as.formula
位以上 lapply
.
至于主要问题:如何设置公式?
我建议先添加两个额外的拦截部分,然后重新排序右侧:
f <- y ~ x2
ff <- update(Formula(f), . ~ . | 1 | 1)
formula(ff, rhs = c(2, 1, 3))
## y ~ 1 | x2 | 1
然后是关于:为什么更新只适用于 .在第一部分?
您期望此代码 returns 相同的结果:
f <- y ~ x2
update(Formula(f), . ~ 1 | . | 1)
## y ~ 1 | . | 1
但显然不是。原因很简单:update()
方法循环遍历所有左手和右手部分。此处,第一个右侧部分 x2
更新为 1
。第二个右侧部分是空的(f
只有一个右侧)因此更新为 .
。同理,对于第三部分。
如果原始公式中恰好有一个右侧,则可以实现您的方法。但是对于几个部分,这将是一团糟。例如,
update(Formula(y ~ x1 | x2 | x3), . ~ . + z1 | 1 | . - x3)
## y ~ x1 + z1 | 1 | 1