目的
二本の直線による,折れ線回帰を行う
使用法
oresen(x, y)
print メソッド
print.oresen(obj)
plot メソッド
plot.oresen(obj, col1="red", col2="blue", ...)
引数
x 独立変数
y 従属変数
obj oresen 関数が返すオブジェクト。クラス名は "oresen"
col1 左側のデータ点と回帰直線の描画色
col2 右側のデータ点と回帰直線の描画色
... plot 関数,abline 関数に渡す引数
ソース
インストールは,以下の 1 行をコピーし,R コンソールにペーストする
source("http://aoki2.si.gunma-u.ac.jp/R/src/oresen.R", encoding="euc-jp")
# 二本の直線による,折れ線回帰を行う
oresen <- function( x, # 独立変数
y) # 従属変数
{
ss <- function(par) # 暫定条件下の残差平方和を求める
{
a <- par[1] # 交点の x 座標
b <- par[2] # 交点の y 座標
c <- par[3] # 左側の直線の傾き
d <- par[4] # 右側の直線の傾き
xl <- x[x < a] # データの左部分
xr <- x[x >= a] # データの右部分
if (length(xl) == 0 || # 左右いずれかにデータがないときには無限大を返す
length(xr) == 0) {
return(Inf)
}
yl <- y[x < a]
yr <- y[x >= a]
yle <- c*(xl-a)+b # 左部分の予測値
yre <- d*(xr-a)+b # 左部分の予測値
retv <- sum((yl-yle)^2)+
sum((yr-yre)^2) # 残差平方和の和
return(retv)
}
names.xy <- c(deparse(substitute(x)), deparse(substitute(y))) # 変数名を控えておく
OK <- complete.cases(x, y) # 欠損値を持つケースを除く
x <- x[OK]
y <- y[OK]
par <- c(mean(x), mean(y), 1, 1) # 初期値
ans <- optim(par, ss, control=list(maxit=1000))
obj <- list(names.xy=names.xy, x=x, y=y, par=ans$par, residuals=ans$value)
class(obj) <- "oresen"
return(obj)
}
# print メソッド
print.oresen <- function(obj)
{
cat(sprintf("残差平方和 = %g\n", obj$residuals))
par <- obj$par
cat(sprintf("交点座標 = ( %g, %g )\n", par[1], par[2]))
cat(sprintf("切片 = %g, 傾き = %g\n", -par[3]*par[1]+par[2], par[3])) # 左側の回帰直線の式
cat(sprintf("切片 = %g, 傾き = %g\n", -par[4]*par[1]+par[2], par[4])) # 右側の回帰直線の式
}
# plot メソッド
plot.oresen <- function(obj, # oresen オブジェクト
xlab=obj$names.xy[1], # x 軸の名前
ylab=obj$names.xy[2], # y 軸の名前
col1="red", # 左側のデータ点と回帰直線の描画色
col2="blue", # 右側のデータ点と回帰直線の描画色
...) # plot 関数などに渡す引数
{
par <- obj$par
x <- obj$x
y <- obj$y
plot(x, y, xlab=xlab, ylab=ylab, col=ifelse(x < par[1], col1, col2), ...)
abline(-par[3]*par[1]+par[2], par[3], col=col1, ...)
abline(-par[4]*par[1]+par[2], par[4], col=col2, ...)
}
使用例
> x <- c(1, 2, 3, 6, 6.1, 4, 5, 7, 8, 9, 10)
> y <- c(2.3, 4.1, 6.4, 12, 12.3, 7.8, 9.7, 14.4, 17.7, 21.5, 24.1)
> ans <- oresen(x, y)
> print(ans) # ans だけでもよい
残差平方和 = 0.730379
交点座標 = ( 5.85152, 11.3351 )
切片 = 0.510833, 傾き = 1.84982
切片 = -6.76013, 傾き = 3.0924
> plot(ans)