我有一个公式,其中包含一些术语和一个数据框(早期model.frame()
调用的输出),其中包含所有这些术语等等。我希望模型框架的子集只包含公式中出现的变量。
ff <- log(Reaction) ~ log(1+Days) + x + y
fr <- data.frame(`log(Reaction)`=1:4,
`log(1+Days)`=1:4,
x=1:4,
y=1:4,
z=1:4,
check.names=FALSE)
所需的结果是fr
减去z
列(fr[,1:4]
作弊 - 我需要一个程序化解决方案......)
不的一些策略:
fr[all.vars(ff)]
## Error in `[.data.frame`(fr, all.vars(ff)) : undefined columns selected
(因为all.vars()
获得了"Reaction"
,而不是log("Reaction")
)
stripwhite <- function(x) gsub("(^ +| +$)","",x)
vars <- stripwhite(unlist(strsplit(as.character(ff)[-1],"\\+")))
fr[vars]
## Error in `[.data.frame`(fr, vars) : undefined columns selected
(因为+
上的拆分会虚假地拆分log(1+Days)
字词。
我一直在考虑走下公式的解析树:
ff[[3]] ## log(1 + Days) + x + y
ff[[3]][[1]] ## `+`
ff[[3]][[2]] ## log(1 + Days) + x
但是我没有把解决方案放在一起,看起来我正在走下一个兔子洞。想法?
答案 0 :(得分:4)
这应该有效:
> fr[gsub(" ","",rownames(attr(terms.formula(ff), "factors")))]
log(Reaction) log(1+Days) x y
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
并向罗马·鲁斯特里克道具指示我指向正确的方向。
编辑:看起来你也可以从“变量”属性中删除它:
fr[gsub(" ","",attr(terms(ff),"variables")[-1])]
编辑2:找到第一个问题案例,涉及I()
或offset()
:
ff <- I(log(Reaction)) ~ I(log(1+Days)) + x + y
fr[gsub(" ","",attr(terms(ff),"variables")[-1])]
然而,使用正则表达式可以很容易地纠正这些问题。但是,如果您遇到调用变量的问题,例如log(x)
,并且在公式中使用I(log(y))
等变量y
,则会变得非常混乱
答案 1 :(得分:0)
在我看来,唯一的问题是fr的第二列名称中缺少空格。用空格重命名并以这种方式拉列:
ff <- log(Reaction) ~ log(1+Days) + x + y
fr <- data.frame(`log(Reaction)`=1:4,
`log(1 + Days)`=1:4,
x=1:4,
y=1:4,
z=1:4,
check.names=FALSE)
fr[labels(terms(ff))]
如果您认为两者之间的唯一区别始终是fr
的名称中包含ff
中的名称的空格,那么上述解决方案就成立了。不过,我更喜欢labels(terms(x))
,因为它看起来有点抽象。
fr[gsub(pattern = ' ', replacement = '', x = labels(terms(ff)))]