Как подогнать синусоидальную волну к данным активности в r на ggplot - PullRequest
1 голос
/ 16 июня 2020

У меня есть данные об активности из большого набора данных, из которого я пытаюсь подогнать синусоидальную волну, чтобы найти соответствующие временные точки пика и спада активности. Данные не обязательно синусоидальные, что может быть проблемой, но тем не менее я хотел бы построить кривую. Я также новичок, когда дело доходит до данных Ritmi c и анализа данных, поэтому не стесняйтесь предоставлять новую информацию или совет. Вот ссылка на данные одной мыши за первую неделю https://www.dropbox.com/s/m08vk7ovij2wcnb/stack_sine_dt.csv?dl=0

          id  eday   act      t
       <fctr> <int> <num>  <num>
    1:   M001     1    17  86400
    2:   M001     1    10  86460
    3:   M001     1    13  86520
    4:   M001     1    14  86580
    5:   M001     1    24  86640
   ---                          
10076:   M001     7     0 690900
10077:   M001     7     1 690960
10078:   M001     7     0 691020
10079:   M001     7     0 691080
10080:   M001     7     0 691140

Я следовал указаниям этого сообщения здесь и получил приличный график, хотя волна, кажется, не достигает пика и спада ежедневно. Я надеюсь наложить его на диаграмму рассеяния ggplot.

# here I fit a wave using lm()
lmfit <- lm(data = dt,
            act ~ sin(2*pi*t/365.25) + cos(2*pi*t/365.25))
# then get relevant parameters
b0 <- coef(lmfit)[1]
alpha <- coef(lmfit)[2]
beta <- coef(lmfit)[3]

r <- sqrt(alpha^2 + beta^2)
phi <- atan2(beta, alpha)

# and fit it to some base plots
par(mfrow=c(1,2))
curve(b0 + r * sin(x + phi), 0, 2*pi, lwd=3, col="Gray",
      main="Overplotted Graphs", xlab="x", ylab="y")
curve(b0 + alpha * sin(x) + beta * cos(x), lwd=3, lty=3, col="Red", add=TRUE)
curve(b0 + r * sin(x + phi) - (b0 + alpha * sin(x) + beta * cos(x)), 
      0, 2*pi, n=257, lwd=3, col="Gray", main="Difference", xlab="x", y="")

Вот результаты базовых графиков, а также график рассеяния ggplot, на который я хотел бы наложить синусоидальную волну.

enter image description hereenter image description here

Ответы [ 2 ]

2 голосов
/ 16 июня 2020

Ваша основная проблема заключается в том, что у вас есть время, измеряемое в секундах, и вам нужен дневной период, но код, который вы используете, предполагает, что время измеряется в днях и что вам нужен годовой период ...

x <- read.csv("stack_sine_dt.csv")

secs_per_day <- 24*3600
x$tday <- x$t/secs_per_day
lmfit <- lm(data = x,
            act ~ sin(2*pi*tday) + cos(2*pi*tday))
b0 <- coef(lmfit)[1]
alpha <- coef(lmfit)[2]
beta <- coef(lmfit)[3]

pframe <- data.frame(tday=seq(min(x$tday),max(x$tday),length=501))
pframe$act <- predict(lmfit,newdata=pframe)

library(ggplot2); theme_set(theme_bw())
ggplot(x,aes(tday,act))+
    geom_point(alpha=0.2) + geom_line(data=pframe,colour="red")

enter image description here

0 голосов
/ 16 июня 2020

Таким образом вы можете наложить подобранную кривую на график рассеяния ggplot (я адаптировал код из здесь ):

library(broom)
library(dplyr)
# here I fit a wave using lm()
lmfit <- lm(data = dt,
            act ~ sin(2*pi*t/36500.25))

bind_cols(dt, lmfit %>% augment) %>% 
  ggplot(aes(t, act...3)) +
  geom_point() +
  geom_ribbon(aes(ymin = .fitted - 1.96*.se.fit, ymax = .fitted + 1.96*.se.fit), alpha = 0.5) + geom_line(mapping = aes(y = .fitted), col = "red")

enter image description here

...