【发布时间】:2012-04-23 15:24:36
【问题描述】:
我正在尝试加速下面的函数(用于以后的引导),该函数执行直线的最小二乘拟合,x 和 y 都有误差。我认为主要的挂断是在while循环中。该函数的输入值是观测值x 和y 以及这些值sx 和sy 中的绝对不确定性。
york <- function(x, y, sx, sy){
x <- cbind(x)
y <- cbind(y)
# initial least squares regression estimation
fit <- lm(y ~ x)
a1 <- as.numeric(fit$coefficients[1]) # intercept
b1 <- as.numeric(fit$coefficients[2]) # slope
e1 <- cbind(as.numeric(fit$residuals)) # residuals
theta.fit <- rbind(a1, b1)
# constants
rho.xy <- 0 # correlation between x and y
# initialize york regression
X <- cbind(1, x)
a <- a1
b <- b1
tol <- 1e-15 # tolerance
d <- tol
i = 0
# york regression
while (d > tol || d == tol){
i <- i + 1
a2 <- a
b2 <- b
theta2 <- rbind(a2, b2)
e <- y - X %*% theta2
w <- 1 / sqrt((sy^2) + (b2^2 * sx^2) - (2 * b2 * sx * sy * rho.xy))
W <- diag(w)
theta <- solve(t(X) %*% (W %*% W) %*% X) %*% t(X) %*% (W %*% W) %*% y
a <- theta[1]
b <- theta[2]
mswd <- (t(e) %*% (W%*%W) %*% e)/(length(x) - 2)
sfit <- sqrt(mswd)
Vo <- solve(t(X) %*% (W %*% W) %*% X)
dif <- b - b2
d <- abs(dif)
}
# format results to data.frame
th <- data.frame(a, b)
names(th) <- c("intercept", "slope")
ft <- data.frame(mswd, sfit)
names(ft) <- c("mswd", "sfit")
df <- data.frame(x, y, sx, sy, as.vector(e), diag(W))
names(df) <- c("x", "y", "sx", "sy", "e", "W")
# store output results
list(coefficients = th,
vcov = Vo,
fit = ft,
df = df)
}
【问题讨论】:
-
只是出于兴趣,你的向量有多大,代码运行需要多长时间?
-
在循环之前为结果向量分配内存,然后避免 cbind 和 rbind。
-
这可能不是一个特别令人满意的答案,但这正是您应该在从 R 调用的编译代码中执行 while 循环的那种函数。
-
运行缓慢的数据并不多。如果是我,我可能会进行一些仔细的调试,以查看耗时这么长的 while 循环中发生了什么。特别是关于您的公差设置和 d 的连续值。
-
还可以尝试使用 R 的内置函数进行加权回归,而不是自己滚动;它可能更快也可能不会更快,但肯定更可靠。
theta <- coef(lsfit(x,y,wt=w^2))
标签: r