2012-07-16 90 views
3

我正在尝试创建泛型函数来处理具有多个似然值的数据框。我想是一个式传递给一个函数执行回归如:更改公式中变量的名称

f <- MRPCM ~ DSEX + IEP + ELL3 + SDRACEM + PARED

MRPCM变量不实际存在于数据帧。取而代之的是五个变量:MRPCM1,MRPCM2,MRPCM3,MRPCM4MRPCM5确实存在。我想要做的是迭代并更新公式(此处为f)以创建五个公式。这可以做到吗? update.formula函数似乎一次可以在整个左侧或右侧工作。我也应该注意到,在这个例子中,我希望改变的变量是因变量,所以update(f, MRPCM1 ~ .)工作。但是,我不知道变量在公式中出现的位置。

例如:

f <- MRPCM + DSEX ~ IEP + ELL3 + SDRACEM + PARED

update.formula(f, as.formula('MRPCM1 ~ .'))

结果在这(请注意,现在DSEX丢失):

MRPCM1 ~ IEP + ELL3 + SDRACEM + PARED

+0

从哪里可以得到合理的变量名? – Chase 2012-07-16 19:47:28

+1

另请参阅'?as.formula'下的示例将字符串粘贴在一起并将其转换为公式。在理论上,应该可能做你想做的 - 让你的问题[reproducible](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example),我们会找到肯定的。 – Chase 2012-07-16 19:49:04

回答

6

这里有一个方法的演示。更复杂的实现可能会更新拟合线性模型(请参阅?update),但这超出了问题的直接范围。

## Make a reproducible example!! 
df <- 
setNames(as.data.frame(matrix(rnorm(96), ncol=8)), 
     c("MRPCM1","MRPCM2","MRPCM3","DSEX","IEP", "ELL3","SDRACEM","PARED")) 

## Construct a template formula 
f <- MRPCM ~ DSEX + IEP + ELL3 + SDRACEM + PARED 

## Workhorse function 
iterlm <- function(formula, data) { 
    ## Find columns in data matching pattern on left hand side of formula 
    LHSpat <- deparse(formula[[2]]) 
    LHSvars <- grep(LHSpat, names(data), value = TRUE) 
    ## Run through matchded columns, repeatedly updating the formula, 
    ## fitting linear model, and extracting whatever results you want. 
    sapply(LHSvars, FUN=function(var) { 
     uf <- update.formula(f, as.formula(paste(var, "~ ."))) 
     coef(lm(uf, df)) 
    }) 
} 

## Try it 
iterlm(f, df) 
##     MRPCM1  MRPCM2  MRPCM3 
## (Intercept) 0.71638942 -0.3883355 0.22202700 
## DSEX  -0.07048994 -0.7478064 0.62590580 
## IEP   -0.22716821 -0.2381982 0.12205780 
## ELL3  -0.44492392 0.1720344 0.41251561 
## SDRACEM  0.21629235 0.4800773 0.02866802 
## PARED  0.07885683 -0.2582598 -0.07996121 
+0

感谢乔希,这几乎是正确的。如果有多个变量需要替换,这不起作用。查看上面原始问题的编辑。 – jbryer 2012-07-16 23:41:12

+0

@jbryer - 嗯,现在已经成为一个不同的问题,我会采取不同的方式。我不会在这上面工作,但这里还有一些提示让你玩弄。 (1)在iterlm()的第一行放入一个'browser()'调用。然后用一个在LHS上有几个变量的公式尝试'iterlm()'。 (2)尝试'f [[2]] [[2]]'和'f [[2]] [[2]] < - as.symbol(“randomString”)'来查看如何修改第一个公式中的变量。 (3)尝试一个'if(length(f [[2]])> 1){}'结构来学习如何编写一个函数来处理带有LHS上的一个或多个变量的公式。 – 2012-07-17 00:02:45