如何根据自己的输出使用FME拟合模型?

时间:2017-01-25 15:38:40

标签: r function nls model-fitting

1。目标+细节

我想找到k的最佳值。 该最佳k是使3个时间点(1950,1993,2014)的观测(Deltaobs)和建模(见下面的等式)数据之间的差异最小化的k。 建模数据是根据起始值(1950年的Deltaobs)计算得出的,取决于给定年份的C14atm和上一年的Deltamodel。

2。示例数据集

2.1。将这些数据保存为dd.txt:

 "year" "lambda" "Deltaobs" "Deltaatm"
1950 0.000120962864400629 -22.1 -22.1
1951 0.000120962864400629 NA -23.2
1952 0.000120962864400629 NA -19.9
1953 0.000120962864400629 NA -20.4
1954 0.000120962864400629 NA -17.9
1955 0.000120962864400629 NA 4.4
1956 0.000120962864400629 NA 38.8
1957 0.000120962864400629 NA 69.9
1958 0.000120962864400629 NA 143.4
1959 0.000120962864400629 NA 233.2
1960 0.000120962864400629 NA 223.9
1961 0.000120962864400629 NA 219.3
1962 0.000120962864400629 NA 342.2
1963 0.000120962864400629 NA 753.52
1964 0.000120962864400629 NA 792.525
1965 0.000120962864400629 NA 733.716666666667
1966 0.000120962864400629 NA 665.975
1967 0.000120962864400629 NA 615.358333333333
1968 0.000120962864400629 NA 563.118181818182
1969 0.000120962864400629 NA 551.258333333333
1970 0.000120962864400629 NA 515.044444444444
1971 0.000120962864400629 NA 491.18
1972 0.000120962864400629 NA 479.716666666667
1973 0.000120962864400629 NA 434.7
1974 0.000120962864400629 NA 410.5
1975 0.000120962864400629 NA 381.241666666667
1976 0.000120962864400629 NA 346.583333333333
1977 0.000120962864400629 NA 330.15
1978 0.000120962864400629 NA 320.433333333333
1979 0.000120962864400629 NA 291.358333333333
1980 0.000120962864400629 NA 265.2
1981 0.000120962864400629 NA 254.608333333333
1982 0.000120962864400629 NA 238.725
1983 0.000120962864400629 NA 226.433333333333
1984 0.000120962864400629 NA 212.316666666667
1985 0.000120962864400629 NA 200.175
1986 0.000120962864400629 NA 189.683333333333
1987 0.000120962864400629 NA 181.158333333333
1988 0.000120962864400629 NA 170.6
1989 0.000120962864400629 NA 162.125
1990 0.000120962864400629 NA 150.583333333333
1991 0.000120962864400629 NA 140.4
1992 0.000120962864400629 NA 134.2
1993 0.000120962864400629 65.1742040000001 125.733333333333
1994 0.000120962864400629 NA 118.725
1995 0.000120962864400629 NA 113.4
1996 0.000120962864400629 NA 105.575
1997 0.000120962864400629 NA 100.891666666667
1998 0.000120962864400629 NA 97.1666666666667
1999 0.000120962864400629 NA 93.0916666666667
2000 0.000120962864400629 NA 86.65
2001 0.000120962864400629 NA 80.1
2002 0.000120962864400629 NA 74.4666666666667
2003 0.000120962864400629 NA 68.8916666666667
2004 0.000120962864400629 NA 65.225
2005 0.000120962864400629 NA 59.175
2006 0.000120962864400629 NA 56.225
2007 0.000120962864400629 NA 51.25
2008 0.000120962864400629 NA 47.775
2009 0.000120962864400629 NA 46.2481593425
2010 0.000120962864400629 NA 51.6519541325
2011 0.000120962864400629 NA 49.330996505
2012 0.000120962864400629 NA 47.19021939
2013 0.000120962864400629 NA 45.2156350325
2014 0.000120962864400629 46.8109329999999 43.3943415675

2.2将数据读入R ####

dd <- read.table("dd.txt", header = TRUE, dec = ".", sep = " ")

3。尝试使用“FME”进行编码

library(FME)

## Predictive function to fit model to observations
lambda <- dd$lambda[1]
tp1950 <- data.frame(year = 1950, 
                     lambda = lambda, 
                     Deltaobs = dd$Deltaobs[dd$year==1950],
                     Deltaatm = dd$Deltaatm[dd$year==1950],
                     Deltamod = dd$Deltaobs[dd$year==1950])

# Predictive function to fit model to observations
Deltafun <- function(pars){
  for(i in 1951:2014){
    year <- i
    Deltaatm <- dd$Deltaatm[dd$year == i]
    Deltaobs <- dd$Deltaobs[dd$year == i]

    k <- pars[1] # parameter to optimize

    f <- function(valPrev, dummy){ #to use the previous value to run model
      k*Deltaatm + valPrev*(1-k-lambda)
    }
    v1 <- get(sprintf("tp%s", i-1))$Deltamod # Starting value is the output 
    n <- i-1950 # Desired number of outputs
    v <- Reduce( f, rep(NA,n), v1, accumulate=TRUE )
    Deltamod <- v[length(n)+1]
    tp <- data.frame(year, lambda, Deltaobs, Deltaatm, Deltamod)
    assign(sprintf("tp%s", i), tp)
  }
  list <- lapply(sprintf("tp%s", 1950:2014), get)
  ddmod <- do.call(rbind, list) %>%
    filter(!is.na(Deltaobs)) %>%
    dplyr::select(year, Deltamod) %>%
    rename(Delta = Deltamod)
  return(ddmod) # ddmod is the modelled dataset to be optimized
}

## Observations dataset
ddobs <- dd %>%
  filter(!is.na(Deltaobs)) %>%
  dplyr::select(year, Deltaobs) %>%
  rename(Delta = Deltaobs)


## Cost function to reduce error between model and observations
Deltacost <- function(pars){
  modelOutput = Deltafun(pars)
  cost = modCost(model = modelOutput, obs = ddobs)
  return(cost)
}

# Initial k
inipars <- c(k=0)

# Fit best model to data
Deltafit <- modFit(f = Deltacost,
                   p = inipars,
                   method = "Port",
                   lower = c(0),
                   upper = c(2))

0 个答案:

没有答案