Hi R users,
I have a question about fitting a cosine curve. I don't know how to set the
approximate starting values. Besides, does the method work for sine curve
as well? Thanks.
Part of the dataset is in the following:
y=c(16.82, 16.72, 16.63, 16.47, 16.84, 16.25, 16.15, 16.83, 17.41, 17.67,
17.62, 17.81, 17.91, 17.85, 17.70, 17.67, 17.45, 17.58, 16.99, 17.10)
t=c(7, 37, 58, 79, 96, 110, 114, 127, 146, 156, 161, 169, 176, 182,
190, 197, 209, 218, 232, 240)
I use the method to fit a curve, but it is different from the real curve,
which can be seen in the figure.
linFit <- lm(y ~ cos(t))
fullFit <- nls(y ~ A*cos(omega*t+C) + B,
start=list(A=coef(linFit)[1],B=coef(linFit)[2],C=0,omega=.4)) #omega cannot
be set to 1, don't know why.
co <- coef(fullFit)
fit <- function(x, a, b, c, d) {a*cos(b*x+c)+d}
plot(x=t, y=y)
curve(fit(x, a=co['A'], b=co['omega'], c=co['C'],d=co['B']), add=TRUE
,lwd=2, col="steelblue")
-------------- next part --------------
A non-text attachment was scrubbed...
Name: curve1.pdf
Type: application/pdf
Size: 29634 bytes
Desc: not available
URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20170620/a99f7d8f/attachment.pdf>
fitting cosine curve
4 messages · Jim Lemon, lily li, Charles C. Berry
Hi lily, You can get fairly good starting values just by eyeballing the curves: plot(y) lines(supsmu(1:20,y)) lines(0.6*cos((1:20)/3+0.6*pi)+17.2) Jim
On Wed, Jun 21, 2017 at 9:17 AM, lily li <chocold12 at gmail.com> wrote:
Hi R users,
I have a question about fitting a cosine curve. I don't know how to set the
approximate starting values. Besides, does the method work for sine curve
as well? Thanks.
Part of the dataset is in the following:
y=c(16.82, 16.72, 16.63, 16.47, 16.84, 16.25, 16.15, 16.83, 17.41, 17.67,
17.62, 17.81, 17.91, 17.85, 17.70, 17.67, 17.45, 17.58, 16.99, 17.10)
t=c(7, 37, 58, 79, 96, 110, 114, 127, 146, 156, 161, 169, 176, 182,
190, 197, 209, 218, 232, 240)
I use the method to fit a curve, but it is different from the real curve,
which can be seen in the figure.
linFit <- lm(y ~ cos(t))
fullFit <- nls(y ~ A*cos(omega*t+C) + B,
start=list(A=coef(linFit)[1],B=coef(linFit)[2],C=0,omega=.4)) #omega cannot
be set to 1, don't know why.
co <- coef(fullFit)
fit <- function(x, a, b, c, d) {a*cos(b*x+c)+d}
plot(x=t, y=y)
curve(fit(x, a=co['A'], b=co['omega'], c=co['C'],d=co['B']), add=TRUE
,lwd=2, col="steelblue")
______________________________________________ R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.
Thanks, that is cool. But would there be a way that can approximate the curve by trying more starting values automatically?
On Tue, Jun 20, 2017 at 5:45 PM, Jim Lemon <drjimlemon at gmail.com> wrote:
Hi lily, You can get fairly good starting values just by eyeballing the curves: plot(y) lines(supsmu(1:20,y)) lines(0.6*cos((1:20)/3+0.6*pi)+17.2) Jim On Wed, Jun 21, 2017 at 9:17 AM, lily li <chocold12 at gmail.com> wrote:
Hi R users, I have a question about fitting a cosine curve. I don't know how to set
the
approximate starting values. Besides, does the method work for sine curve as well? Thanks. Part of the dataset is in the following: y=c(16.82, 16.72, 16.63, 16.47, 16.84, 16.25, 16.15, 16.83, 17.41, 17.67, 17.62, 17.81, 17.91, 17.85, 17.70, 17.67, 17.45, 17.58, 16.99, 17.10) t=c(7, 37, 58, 79, 96, 110, 114, 127, 146, 156, 161, 169, 176, 182, 190, 197, 209, 218, 232, 240) I use the method to fit a curve, but it is different from the real curve, which can be seen in the figure. linFit <- lm(y ~ cos(t)) fullFit <- nls(y ~ A*cos(omega*t+C) + B, start=list(A=coef(linFit)[1],B=coef(linFit)[2],C=0,omega=.4)) #omega
cannot
be set to 1, don't know why.
co <- coef(fullFit)
fit <- function(x, a, b, c, d) {a*cos(b*x+c)+d}
plot(x=t, y=y)
curve(fit(x, a=co['A'], b=co['omega'], c=co['C'],d=co['B']), add=TRUE
,lwd=2, col="steelblue")
______________________________________________ R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/
posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
On Tue, 20 Jun 2017, lily li wrote:
Hi R users, I have a question about fitting a cosine curve. I don't know how to set the approximate starting values.
See
Y.L. Tong (1976) Biometrics 32:85-94
The method is known as `cosinor' analysis. It takes advantage of the
*intrinsic* linearity of y = a + b * cos( omega*t - c ), when omega is
given.
It you are scratching your head saying 'that thing is not linear', you
need to go back to your linear models text and review what `linearity'
actually refers to. Also, reading the Tong paper is recomended as you
will need the transformations given there in any case.
What you end up doing is fitting
fit <- lm(y~cos(t.times.omega)+sin(t.times.omega))
and then transforming coef(fit) to get back a, b, and c. So, you only need
to have omega. If it is not obvious what value to use, then that will be
more of a challenge.
The paper gives asymptotics for the dispersion matrix of (a, b, c), I
recall.
Besides, does the method work for sine curve as well?
Seriously? See https://en.wikipedia.org/wiki/List_of_trigonometric_identities#Shifts_and_periodicity HTH, Chuck