查找本地 minima/maxima 并仅使用此范围进行绘图
Find local minima/maxima and and use only this range for plotting
下面我有一些数据。请以 CSV 格式粘贴到文本文件中,因为我不知道如何将其导出为矢量 :)
无论如何,在绘制散点图时您会注意到有一个最大值。我怎样才能只从 x = 0
到 x = max(y)
范围内进行拟合(在这种情况下只是线性拟合,虽然不完全准确),然后从最大值到最后进行另一个拟合(可能是指数衰减)观点?请参阅下面的草图。
time;intensity
0;2.17645
30;1.93959
60;2.66259
90;2.90125
120;2.5585
150;2.68808
180;3.06872
210;2.78406
240;3.03446
270;3.00371
300;2.92382
330;2.9213
360;2.86571
390;2.67248
420;2.48212
450;2.58491
480;2.53085
510;2.46214
540;2.38609
570;2.03002
600;1.8867
630;1.75795
660;1.69764
690;1.71163
720;1.59365
750;1.67867
780;1.59154
810;1.47798
840;1.43321
870;1.4091
900;1.32017
930;1.31044
960;1.28891
990;1.31004
1020;1.24349
1050;1.17192
1080;1.08548
1110;1.13026
1140;1.14576
1170;1.12595
1200;1.16716
1230;1.15284
1260;1.12913
1290;1.14195
1320;1.11694
1350;1.16297
1380;1.04345
1410;1.0932
1440;1.10847
1470;1.09431
1500;1.02416
1530;1.00733
1560;1.15768
1590;1.09288
1620;1.11773
1650;1.15572
1680;1.02918
1710;1.12721
1740;1.14438
最简单的方法是在出现最大值的地方将数据分成两部分并独立地拟合它们?
可以通过以下代码实现;
data <- read.csv('./in.csv')
max <- which.max(data$intensity)
start <- data[1:max,]
end <- data[max:dim(data)[1],]
which
只是 returns 达到最大值的索引,并在其上拆分,dim
returns 数据框的形状,我们正在选择行数。
如果您希望平滑数据的顶部而不使用显式最大值,则有一个使用 rollaply here.
的很好的示例
使用 ggplot2
中的 stat_smooth
和 geom_smooth
来计算和绘制适合您的数据的函数,并使用 subset
函数来告诉它们适合数据的哪些部分:
library( ggplot2 )
X <- read.delim( "data.csv", sep=";" )
pt <- X$time[ which.max( X$intensity ) ] # Identify the inflection point
g <- ggplot( X, aes( x=time, y=intensity ) ) +
geom_point() +
stat_smooth( data=subset( X, time<=pt ), method="lm", col="blue", se=FALSE ) +
geom_smooth( data=subset( X, time>=pt ), method="glm", col="red", se=FALSE,
method.args=list(family=gaussian(link="log")) )
请注意,指数衰减似乎不太适合您的数据:
下面我有一些数据。请以 CSV 格式粘贴到文本文件中,因为我不知道如何将其导出为矢量 :)
无论如何,在绘制散点图时您会注意到有一个最大值。我怎样才能只从 x = 0
到 x = max(y)
范围内进行拟合(在这种情况下只是线性拟合,虽然不完全准确),然后从最大值到最后进行另一个拟合(可能是指数衰减)观点?请参阅下面的草图。
time;intensity
0;2.17645
30;1.93959
60;2.66259
90;2.90125
120;2.5585
150;2.68808
180;3.06872
210;2.78406
240;3.03446
270;3.00371
300;2.92382
330;2.9213
360;2.86571
390;2.67248
420;2.48212
450;2.58491
480;2.53085
510;2.46214
540;2.38609
570;2.03002
600;1.8867
630;1.75795
660;1.69764
690;1.71163
720;1.59365
750;1.67867
780;1.59154
810;1.47798
840;1.43321
870;1.4091
900;1.32017
930;1.31044
960;1.28891
990;1.31004
1020;1.24349
1050;1.17192
1080;1.08548
1110;1.13026
1140;1.14576
1170;1.12595
1200;1.16716
1230;1.15284
1260;1.12913
1290;1.14195
1320;1.11694
1350;1.16297
1380;1.04345
1410;1.0932
1440;1.10847
1470;1.09431
1500;1.02416
1530;1.00733
1560;1.15768
1590;1.09288
1620;1.11773
1650;1.15572
1680;1.02918
1710;1.12721
1740;1.14438
最简单的方法是在出现最大值的地方将数据分成两部分并独立地拟合它们?
可以通过以下代码实现;
data <- read.csv('./in.csv')
max <- which.max(data$intensity)
start <- data[1:max,]
end <- data[max:dim(data)[1],]
which
只是 returns 达到最大值的索引,并在其上拆分,dim
returns 数据框的形状,我们正在选择行数。
如果您希望平滑数据的顶部而不使用显式最大值,则有一个使用 rollaply here.
的很好的示例使用 ggplot2
中的 stat_smooth
和 geom_smooth
来计算和绘制适合您的数据的函数,并使用 subset
函数来告诉它们适合数据的哪些部分:
library( ggplot2 )
X <- read.delim( "data.csv", sep=";" )
pt <- X$time[ which.max( X$intensity ) ] # Identify the inflection point
g <- ggplot( X, aes( x=time, y=intensity ) ) +
geom_point() +
stat_smooth( data=subset( X, time<=pt ), method="lm", col="blue", se=FALSE ) +
geom_smooth( data=subset( X, time>=pt ), method="glm", col="red", se=FALSE,
method.args=list(family=gaussian(link="log")) )
请注意,指数衰减似乎不太适合您的数据: