我是R的新手,我正在尝试将smooth.spline()应用于大型数据帧。我已经研究了相关的线程(“对数据帧的每一行应用n个函数的列表",”如何应用样条基矩阵“,等等)。以下是我的数据框架和我到目前为止尝试过的内容:
> dim(mUnique)
[1] 4565 9
> str(mUnique)
'data.frame': 4565 obs. of 9 variables:
$ Group.1: Factor w/ 4565 levels "mal_mito_1","mal_mito_2",..: 1 2 3 4 5 6 7 8 9 10 ...
$ h0 : num 0.18 -0.025 0.212 0.015 0.12 ...
$ h6 : num -0.04 -0.305 -0.188 -0.185 -0.09 ...
$ h12 : num -0.86 -1.1 -1.01 -1.04 -0.91 ...
$ h18 : num -0.73 -1.215 -1.222 -0.355 -0.65 ...
$ h24 : num 0.04 0.025 -0.143 0.295 0.09 ...
$ h30 : num -0.14 1.275 0.732 -0.015 -0.27 ...
$ h36 : num 1.44 1.795 1.627 0.385 0.91 ...
$ h42 : num 1.49 1.385 1.397 0.305 1.12 ...
> head(mUnique)
ID h0 h6 h12 h18 h24 h30 h36 h42
1 mal_mito_1 0.1800 -0.0400 -0.8600 -0.7300 0.0400 -0.1400 1.4400 1.4900
2 mal_mito_2 -0.0250 -0.3050 -1.1050 -1.2150 0.0250 1.2750 1.7950 1.3850
3 mal_mito_3 0.2125 -0.1875 -1.0075 -1.2225 -0.1425 0.7325 1.6275 1.3975
4 mal_rna_10_rRNA 0.0150 -0.1850 -1.0450 -0.3550 0.2950 -0.0150 0.3850 0.3050
5 mal_rna_11_rRNA 0.1200 -0.0900 -0.9100 -0.6500 0.0900 -0.2700 0.9100 1.1200
6 mal_rna_14_rRNA 0.0200 -0.0200 -0.8400 -0.6600 0.1700 -0.0900 0.6200 0.0800 我可以在每一行单独应用smooth.spline,到目前为止,使用spline()看起来很好(我想要48分。我将在稍后了解如何使用smoooth.spline spar完成此操作):
> time <- c(0,6,12,18,24,30,36,42)
> plot(time, mUnique[1, 2:9])
> smooth <- smooth.spline(time, mUnique[1, 2:9])
> lines(smooth, col="blue")
> splin <-spline(time, mUnique[1, 2:9], n=48)
> lines(splin, col="blue") 我的问题是,我假设是基本的,但是我如何将smooth.spline()或spline()应用于整个数据帧,并返回一个矩阵4565 * 49,其中我有平滑样条的每个节点的坐标?我真的不关心绘制这些数据。
我试过了:
> smooth <- smooth.spline(time, mUnique[, 2:9]|factor(ID))现在,我不知道该怎么办。这是一个循环的问题吗?
提前谢谢你
发布于 2011-03-29 19:34:51
这就是你要找的吗?
time <- c(0,6,12,18,24,30,36,42)
t(
apply(mUnique[-1],1,
function(x){
tmp <- smooth.spline(time,x)
predict(tmp,seq(min(time),max(time),length.out=49))$y
}
)
)它应该会给出你所描述的矩阵。
额外解释:
我删除了第一列(mUnique[-1])。这是列表的方法,你也可以做mUnique[,-1],这是矩阵的等价物。这两种方法都适用于数据帧。
然后我告诉apply将函数应用到行上,这是第一个边距。
我定义的函数,
function(x){
tmp <- smooth.spline(time,x)
predict(tmp,seq(min(time),max(time),length.out=49))$y
}是两行代码:
seq(min(time),max(time),length.out=49))的预测,并取预测的y值。此函数定义中的x是传递的参数。在本例中,它表示由apply函数传递的一行。
最后,我将转置矩阵(t)以将其转换为您要求的格式。
下面的测试用例可以很好地运行代码:
mUnique <- read.table(textConnection("
ID h0 h6 h12 h18 h24 h30 h36 h42
mal_mito_1 0.1800 -0.0400 -0.8600 -0.7300 0.0400 -0.1400 1.4400 1.4900
mal_mito_2 -0.0250 -0.3050 -1.1050 -1.2150 0.0250 1.2750 1.7950 1.3850
mal_mito_3 0.2125 -0.1875 -1.0075 -1.2225 -0.1425 0.7325 1.6275 1.3975
mal_rna_10_rRNA 0.0150 -0.1850 -1.0450 -0.3550 0.2950 -0.0150 0.3850 0.3050
mal_rna_11_rRNA 0.1200 -0.0900 -0.9100 -0.6500 0.0900 -0.2700 0.9100 1.1200
mal_rna_14_rRNA 0.0200 -0.0200 -0.8400 -0.6600 0.1700 -0.0900 0.6200 0.0800 ")
,header=T)
time <- c(0,6,12,18,24,30,36,42)确保在运行我的代码之前定义了time ...
发布于 2011-03-29 19:56:12
使用object dat中的数据片段,我们可以做(我认为)您想要做的事情。首先,我们编写一个小包装函数,该函数通过smooth.spline()拟合平滑样条,然后预测该样条对一组n位置的响应。您要求提供n = 48,因此我们将使用它作为默认值。
下面是一个这样的包装器函数:
SSpline <- function(x, y, n = 48, ...) {
## fit the spline to x, and y
mod <- smooth.spline(x, y, ...)
## predict from mod for n points over range of x
pred.dat <- seq(from = min(x), to = max(x), length.out = n)
## predict
preds <- predict(mod, x = pred.dat)
## return
preds
}我们检查您的数据的第一行是否有效:
> res <- SSpline(time, dat[1, 2:9])
> res
$x
[1] 0.000000 0.893617 1.787234 2.680851 3.574468 4.468085 5.361702
[8] 6.255319 7.148936 8.042553 8.936170 9.829787 10.723404 11.617021
[15] 12.510638 13.404255 14.297872 15.191489 16.085106 16.978723 17.872340
[22] 18.765957 19.659574 20.553191 21.446809 22.340426 23.234043 24.127660
[29] 25.021277 25.914894 26.808511 27.702128 28.595745 29.489362 30.382979
[36] 31.276596 32.170213 33.063830 33.957447 34.851064 35.744681 36.638298
[43] 37.531915 38.425532 39.319149 40.212766 41.106383 42.000000
$y
[1] 0.052349585 0.001126837 -0.049851737 -0.100341294 -0.150096991
[6] -0.198873984 -0.246427429 -0.292510695 -0.336721159 -0.378381377
[11] -0.416785932 -0.451229405 -0.481006377 -0.505411429 -0.523759816
[16] -0.535714043 -0.541224748 -0.540251293 -0.532753040 -0.518689349
[21] -0.498019582 -0.470750611 -0.437182514 -0.397727107 -0.352796426
[26] -0.302802508 -0.248157388 -0.189272880 -0.126447574 -0.059682959
[31] 0.011067616 0.085850805 0.164713260 0.247701633 0.334851537
[36] 0.425833795 0.519879613 0.616194020 0.713982047 0.812448724
[41] 0.910799082 1.008296769 1.104781306 1.200419068 1.295380186
[46] 1.389834788 1.483953003 1.577904960
> plot(time, dat[1, 2:9])
> lines(res, col = "blue")这就给出了:

这似乎是可行的,所以现在我们可以对数据集应用该函数,只保留SSpline()返回的对象的$y组件。为此,我们使用apply()
> res2 <- apply(dat[, 2:9], 1,
+ function(y, x, ...) { SSpline(x, y, ...)$y },
+ x = time)
> head(res2)
1 2 3 4 5 6
[1,] 0.052349585 -0.02500000 0.21250000 -0.06117869 -0.02153366 -0.02295792
[2,] 0.001126837 -0.04293509 0.17175460 -0.10994988 -0.06538250 -0.06191095
[3,] -0.049851737 -0.06407856 0.12846458 -0.15838412 -0.10899505 -0.10074427
[4,] -0.100341294 -0.09168227 0.08005550 -0.20614476 -0.15213426 -0.13933920
[5,] -0.150096991 -0.12899810 0.02395291 -0.25289514 -0.19456304 -0.17757705
[6,] -0.198873984 -0.17927793 -0.04241763 -0.29829862 -0.23604434 -0.21533911现在res2包含48行和6列,这6列指的是这里使用的每一行dat。如果你想反其道而行之,只需转置res2:t(res2)即可。
我们可以通过一个简单的matplot()调用来查看所做的工作:
> matplot(x = seq(min(time), max(time), length = 48),
+ y = res2, type = "l")这会产生:

https://stackoverflow.com/questions/5470983
复制相似问题