Variabel respon y adalah fungsi nonlinier dari sejumlah variabel prediktor X (dalam data nyata saya respon didistribusikan secara biner, tetapi di sini saya menggunakan nilai yang didistribusikan secara normal untuk kesederhanaan). Saya dapat memodelkan hubungan antara prediktor dan respons menggunakan splines / smooths (misalnya, model GAM dalam mgcv
paket di R).
Sejauh ini bagus. Namun, setiap respons adalah hasil dari proses yang berkembang seiring waktu. Yaitu, hubungan antara prediktor X dan respons y berubah seiring waktu. Untuk setiap respons, saya memiliki data untuk prediktor atas sejumlah titik waktu di sekitar respons. Artinya, ada satu respons per kelompok titik waktu (bukan berarti responsnya berkembang seiring waktu).
Beberapa ilustrasi mungkin membantu pada saat ini. Berikut adalah beberapa data dengan parameter yang diketahui (kode di bawah) dan kemudian diplot menggunakan ggplot2 (menentukan metode GAM dan cara yang lebih tepat), dengan waktu dalam segi-segi. Sebagai ilustrasi, y adalah fungsi kuadratik dari x1, dan tanda dan besarnya hubungan ini berubah sebagai fungsi waktu.
Hubungan antara x2 dan y adalah lingkaran, sesuai dengan peningkatan y dengan arah tertentu x2. Amplitudo hubungan ini memodulasi dari waktu ke waktu. (Dimodelkan dalam ggplot menggunakan gam yang menentukan "cc" bundar kubik halus).
Saya ingin memodelkan perubahan (nonlinear) pada setiap prediktor sebagai fungsi waktu menggunakan sesuatu seperti spline dua dimensi.
Saya telah mempertimbangkan menggunakan smooth dua dimensi dalam paket mgcv (sesuatu seperti te(x1,t)
), kecuali bahwa ini akan membutuhkan data dalam bentuk panjang (yaitu satu kolom titik waktu). Saya pikir ini tidak tepat, karena satu respons dikaitkan dengan semua titik waktu - jadi mengatur data dalam bentuk panjang (sehingga menggandakan respons yang sama di beberapa baris matriks desain) akan melanggar independensi pengamatan. Data saya saat ini disusun dengan kolom (y, x1.t1, x1.t2, x1.t3, ..., x2.t1, x2.t2, ...)
dan saya pikir ini adalah format yang paling tepat.
Saya ingin tahu:
- apakah ada cara yang lebih baik untuk memodelkan data ini
- jika demikian, seperti apa bentuk desain matriks / formula model tersebut. Pada akhirnya saya ingin memperkirakan koefisien model menggunakan inferensi Bayesian dalam paket mcmc seperti JAGS, jadi saya ingin tahu cara menulis spline dua dimensi.
Kode R untuk mereproduksi contoh saya:
library(ggplot2)
library(mgcv)
#-------------------
# start by generating some data with known relationships between two variables,
# one periodic, over time.
set.seed(123)
nTimeBins <- 6
nSamples <- 500
# the relationship between x1, x2 and y are not linear.
# y = 0.4*x1^2 -1.2*x1 + 0.4*sin(x2) + 1.2*cos(x2)
# the relationship between x1, x2 and y evolve over time.
x1.timeMult <- cos(seq(-pi,pi,length=nTimeBins))
x2.timeMult <- cos(seq(-pi/2,pi/2,length=nTimeBins))
qplot(x=1:nTimeBins,y=x1.timeMult,geom="line") +
geom_line(aes(x=1:nTimeBins,y=x2.timeMult,colour="red")) +
guides(colour=FALSE) + ylab("multiplier")
df <- data.frame(setup=rep(NA,times=nSamples))
for (time in 1 : nTimeBins){
text <- paste('df$x1.t',time,' <- runif(nSamples,min=-3,max=3)',sep="")
eval(parse(text=text))
text <- paste('df$x2.t',time,' <- runif(nSamples,min=-pi,max=pi)',sep="")
eval(parse(text=text))
}
df$setup <- NULL
# each y is a function of x over time.
text <- 'y <- '
# replicated from above for reference:
# y = 0.4*x1^2 -1.2*x1 + 0.4*sin(x2) + 1.2*cos(x2)
for (time in 1 : nTimeBins){
text <- paste(text,'(0.4*x1.t',time,'^2-1.2*x1.t',time,') *
x1.timeMult[',time,'] + (0.4*sin(x2.t',time,') +
1.2*cos(x2.t',time,'))*x2.timeMult[',time,'] + ',sep="")
}
text <- paste(text,'rnorm(nSamples,sd=0.2)')
attach(df)
eval(parse(text=text))
df$y <- y
#-------------------
# transform into long form data for plotting:
df.long <- data.frame(y=rep(df$y,times=nTimeBins))
textX1 <- 'df.long$x1 <- c('
textX2 <- 'df.long$x2 <- c('
for (time in 1:nTimeBins){
textX1 <- paste(textX1,'x1.t',time,',',sep="")
textX2 <- paste(textX2,'x2.t',time,',',sep="")
}
textX1 <- paste(textX1,'NULL)',sep="")
textX2 <- paste(textX2,'NULL)',sep="")
eval(parse(text=textX1))
eval(parse(text=textX2))
# time stamp:
df.long$t <- factor(rep(1:nTimeBins,each=nSamples))
#-------------------
# plot relationships over time using GAM fits in ggplot:
p1 <- ggplot(df.long,aes(x=x1,y=y)) + geom_point() +
stat_smooth(method="gam",formula=y ~ s(x,bs="cs",k=4)) +
facet_wrap(~ t, ncol=3) + opts(title="x1 versus y over time")
p1
p2 <- ggplot(df.long,aes(x=x2,y=y)) + geom_point() +
stat_smooth(method="gam",formula=y ~ s(x,bs="cc",k=5)) +
facet_wrap(~ t, ncol=3) + opts(title="x2 versus y over time")
p2