用于具有任意列数

时间:2015-09-19 19:05:22

标签: r lm

我正在尝试编写一个适用于具有任意列数的数据框的函数。该函数的一部分涉及lm命令,我遇到了复杂问题。对于此示例,我将使用以下数据:

x1 <- runif(100)
x2 <- runif(100)

z1 <- runif(100)
z2 <- runif(100)

y <- 0.2 + 0.7*x1 + 0.7*x2 + 0.4*z1 + 0.4*z2 + 0.8*z1*z2 + 0.8*z1^2 + 0.8*z2^2 + rnorm(100,0,.2) 

df <- data.frame(y,x1,x2,z1,z2)

该功能被编程为记录用户提供了多少x和多少z,并且x始终出现在数据框中在单个y变量之后和z变量之前。因此,在这种情况下,在数据帧的第一列中有2个x和2个z,当然还有1个y。该函数将x和z的数量记录为变量n.x和n.z

n.x <- 2
n.z <- 2

我想在x&x和s上的二阶多项式中包含y的回归,但它必须在x的数量方面具有灵活性。和z由用户提供。

我知道如果我能直接观察df,那么我可以简单地使用

linear.model <- lm(y ~ cbind(x1,x2) + poly(cbind(z1,z2),degree=2),data=df) 

但在某些情况下,可能会有更多或更少的x和/或z。我尝试了以下内容,因为它知道它不太可行:

linear.model <- lm(df$y ~ cbind(df[,2:(n.x+1)]) + poly(cbind(df[,(n.x+2):(n.x+n.z+1)]),degree=2)) 

当然它没有用。这个问题的关键是它必须使用lm中的n.x和n.z变量来指示数据框中x和s和z所在的位置。

非常感谢您的帮助。谢谢!

2 个答案:

答案 0 :(得分:2)

您可以从数据框名称和字符串中创建字符串 将其转换为as.formula

xs <- paste(names(df)[2:(1 + n.x)], collapse = ", ")
zs <- paste(names(df)[(2 + n.x):(1 + n.x + n.z)], collapse = ", ")

s_formula <- sprintf("y ~ cbind(%s) + poly(cbind(%s),degree=2)", xs, zs)

linear.model <- lm(as.formula(s_formula), data=df)

答案 1 :(得分:2)

这是另一种选择。代码更复杂,但我认为最终结果更容易理解。

cn <- colnames(df)
zz <- cn[grepl("^z",cn)]
xx <- cn[grepl("^x",cn)]
form <- paste0("y~",
               paste(paste(paste(xx,collapse="+")),
                     paste(zz,collapse="*"),
                     paste(paste0("I(",zz,"^2)"),collapse="+"), 
                     sep="+"))
form
# [1] "y~x1+x2+z1*z2+I(z1^2)+I(z2^2)
fit <- lm(as.formula(form),df)
coef(summary(fit))
#               Estimate Std. Error    t value     Pr(>|t|)
# (Intercept) 0.20295008 0.11381558 1.78314847 7.786013e-02
# x1          0.68572092 0.08322408 8.23945324 1.141453e-12
# x2          0.70859080 0.07803392 9.08054860 1.964402e-14
# z1          0.74963604 0.32518472 2.30526218 2.340025e-02
# z2          0.01230116 0.34891211 0.03525577 9.719522e-01
# I(z1^2)     0.50320062 0.31074776 1.61932181 1.088012e-01
# I(z2^2)     1.13595678 0.30034582 3.78216276 2.762723e-04
# z1:z2       0.86561996 0.28552946 3.03163095 3.159388e-03

请注意,在lm(...)的公式参数中,*运算符会生成所有线性和交叉项,因此,例如,z1*z2*z3将生成所有项z1 + z2 + z3 + z1:z2 + z1:z3 + z2:z3等。