Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fit data with non linear function and plot data and fit with ggplot()

A measurement shows a signal that is formed like a square root function with offset and a factor. How can I find the coefficients and plot the raw data and the fitted curve in one plot?

require(ggplot2)
require(nlmrt)  # may be this will help later..?

# generate simulated measurement data

time <- seq(-10,20,0.2)

signal <- sqrt(time + 2) # generate sqrt signal; includes some NA
signal[is.na(signal)] <- 0 # set all NA to zero
signal <- signal + rnorm(length(time)) * 0.1  # add noise

df <- data.frame(x=time, y=signal)

# find coefficiants for y ~ b * sqrt(x - a)
# no idea how...

# plot raw data and fitted curve in one ggplot diagram

ggplot()+
    geom_point(data=df, aes(x=x, y=y))

enter image description here

like image 774
Jonas Stein Avatar asked Jun 14 '13 17:06

Jonas Stein


1 Answers

Provided you know where the cutpoint is and that the value before the cutpoint is zero:

sfun <- function(x,brk,a=1) {
    ifelse(x<brk,0,suppressWarnings(a*sqrt(x-brk)))
}

(suppressWarnings() is there because ifelse evaluates both the if and the else cases for all values of x, and we don't want warnings about taking the square root of negative numbers)

Test (not shown):

curve(sfun(x,1,1),from=0,to=10) ## test (not shown)

Simulate some data:

x <- seq(0,10,length=101)
set.seed(1)
y <- rnorm(length(x),sfun(x,1,1),sd=0.25)
DF <- data.frame(x,y)

Since all we need to figure out is how the square root function is scaled, we can do this with a regression through the origin (take out the -1 if you want to allow the value below the cutpoint to be non-zero):

library("ggplot2")
theme_set(theme_bw())
ggplot(DF,aes(x,y))+geom_point()+
    geom_smooth(method="lm",
                formula=y~sfun(x,brk=1)-1)
ggsave("truncsqrt.png")

enter image description here

like image 154
Ben Bolker Avatar answered Oct 29 '22 18:10

Ben Bolker