1. Pendahuluan

Analisis data pertumbuhan, baik pada bidang biologi, pertanian, maupun ekonomi, sering kali memperlihatkan pola yang tidak dapat dijelaskan secara memadai oleh model linear sederhana. Pertumbuhan organisme hidup, misalnya tanaman atau hewan, biasanya mengalami fase-fase tertentu: fase awal dengan pertumbuhan lambat, fase percepatan, fase pertumbuhan maksimal, hingga fase melambat ketika mendekati batas biologis atau kapasitas lingkungan. Pola yang demikian membentuk kurva yang bersifat nonlinear, sehingga model nonlinear menjadi pilihan yang lebih tepat untuk menjelaskannya.

Dalam laporan ini, dilakukan studi pada dataset nyata berupa pertumbuhan pohon jeruk (Orange) yang tersedia di R. Analisis mencakup penerapan model nonlinear menggunakan fungsi nls(), estimasi parameter-parameter penting, interpretasi hasil dalam konteks biologis, serta evaluasi goodness-of-fit melalui ukuran statistik seperti SSE, R², dan AIC. Selain itu, sebagai pembanding, dilakukan pula pemodelan regresi linear sederhana untuk menilai sejauh mana pendekatan linear dapat (atau tidak dapat) mewakili dinamika pertumbuhan.

Tidak hanya terbatas pada data nyata, laporan ini juga menyertakan simulasi data pertumbuhan eksponensial, misalnya untuk menggambarkan dinamika pertumbuhan populasi bakteri. Simulasi ini berfungsi untuk menguji sejauh mana nls() dapat mengestimasi parameter dari data yang diketahui model dasarnya. Hasil simulasi akan menunjukkan kekuatan metode nonlinear dalam mengidentifikasi parameter meskipun terdapat gangguan (noise) dalam data.

Dengan demikian, laporan ini tidak hanya memberikan gambaran teknis tentang penerapan regresi nonlinear dalam R, tetapi juga menekankan aspek interpretasi biologis/ekonomis dari parameter, perbandingan performa dengan model linear, serta implikasi praktis dalam pemodelan data pertumbuhan di dunia nyata.

2. Data nyata: dataset Orange (pertumbuhan pohon jeruk)

Dataset Orange bawaan R berisi pengukuran keliling batang pohon (circumference) pada beberapa pohon pada usia (age) tertentu. Pola umumnya memperlihatkan pertumbuhan nonlinier (cepat di awal kemudian melambat).

Rumus sederhana yang akan dicoba:

\[y = \frac{Asym}{1 + e^{(xmid - x)/scale}}\]

atau model asimptotik (monomolecular / asymptotic):

\[y = Asym - A e^{-b x}\]

\[y = \beta_0 + \beta_1 x + \varepsilon\]

2.1. Persiapan data dan eksplorasi

data("Orange")
Orange <- as_tibble(Orange)
Orange
## # A tibble: 35 × 3
##    Tree    age circumference
##    <ord> <dbl>         <dbl>
##  1 1       118            30
##  2 1       484            58
##  3 1       664            87
##  4 1      1004           115
##  5 1      1231           120
##  6 1      1372           142
##  7 1      1582           145
##  8 2       118            33
##  9 2       484            69
## 10 2       664           111
## # ℹ 25 more rows
# Plot eksplorasi keseluruhan
ggplot(Orange, aes(x = age, y = circumference, color = factor(Tree))) +
  geom_point() +
  geom_line() +
  labs(color = "Tree", title = "Data Orange: circumference vs age", x = "Age (days)", y = "Circumference (mm)") +
  theme_minimal()

Interpretasi eksplorasi: dari plot terlihat hubungan nonlinier: laju pertumbuhan menurun pada usia lebih tua.

2.2. Fitting model nonlinear menggunakan nls()

Kita akan mencoba model asimptotik yang sering cocok untuk pertumbuhan pohon: paket base menyediakan fungsi self-start SSasymp atau SSlogis. Di sini gunakan model logistic self-start (SSlogis) dan model asimptotik (SSasymp).

# Model logistic (self-start)
fit_logis <- nls(circumference ~ SSlogis(age, Asym, xmid, scal), data = Orange)
summary(fit_logis)
## 
## Formula: circumference ~ SSlogis(age, Asym, xmid, scal)
## 
## Parameters:
##      Estimate Std. Error t value Pr(>|t|)    
## Asym   192.69      20.24   9.518 7.48e-11 ***
## xmid   728.76     107.30   6.792 1.12e-07 ***
## scal   353.53      81.47   4.339 0.000134 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 23.37 on 32 degrees of freedom
## 
## Number of iterations to convergence: 0 
## Achieved convergence tolerance: 2.201e-06
# Model asymptotic (self-start)
fit_asymp <- nls(circumference ~ SSasymp(age, Asym, R0, lrc), data = Orange)
summary(fit_asymp)
## 
## Formula: circumference ~ SSasymp(age, Asym, R0, lrc)
## 
## Parameters:
##      Estimate Std. Error t value Pr(>|t|)    
## Asym  559.283    706.984   0.791    0.435    
## R0     10.819     13.806   0.784    0.439    
## lrc    -8.344      1.573  -5.304 8.21e-06 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 23.94 on 32 degrees of freedom
## 
## Number of iterations to convergence: 0 
## Achieved convergence tolerance: 2.329e-06
# Ekstrak koef
coef(fit_logis)
##     Asym     xmid     scal 
## 192.6873 728.7552 353.5326
coef(fit_asymp)
##      Asym        R0       lrc 
## 559.28250  10.81873  -8.34403

Interpretasi parameter:
- Asym: nilai asimptotik (perkiraan nilai keliling maksimum ketika usia sangat besar).
- xmid (logistic): umur pada titik tengah pertumbuhan (titik infleksi).
- scal (logistic): skala waktu yang mengendalikan kemiringan pada titik tengah.
- R0, lrc (SSasymp): parameter transformasi terkait intercept efektif dan laju pertumbuhan.

2.3. Goodness-of-fit untuk model nonlinear

# Fungsi bantu
gof_stats <- function(model, data, resp){
  pred <- predict(model, newdata = data)
  resid <- data[[resp]] - pred
  SSE <- sum(resid^2)
  SST <- sum((data[[resp]] - mean(data[[resp]]))^2)
  R2_pseudo <- 1 - SSE / SST
  AIC_val <- AIC(model)
  tibble(SSE = SSE, SST = SST, R2_pseudo = R2_pseudo, AIC = AIC_val)
}

gof_logis <- gof_stats(fit_logis, Orange, "circumference")
gof_asymp <- gof_stats(fit_asymp, Orange, "circumference")

bind_rows(Logistic = gof_logis, Asymptotic = gof_asymp, .id = "model")
## # A tibble: 2 × 5
##   model         SSE     SST R2_pseudo   AIC
##   <chr>       <dbl>   <dbl>     <dbl> <dbl>
## 1 Logistic   17480. 112366.     0.844  325.
## 2 Asymptotic 18335. 112366.     0.837  326.

2.4. Visualisasi hasil fit nonlinear

Orange_plot <- Orange %>%
  mutate(pred_logis = predict(fit_logis, newdata = Orange),
         pred_asymp = predict(fit_asymp, newdata = Orange))

ggplot(Orange_plot, aes(x = age, y = circumference)) +
  geom_point(aes(color = factor(Tree))) +
  geom_line(aes(y = pred_logis), size = 1, linetype = "dashed") +
  geom_line(aes(y = pred_asymp), size = 1, linetype = "solid") +
  labs(title = "Model Nonlinear: Logistic (dashed) vs Asymptotic (solid)", x = "Age", y = "Circumference") +
  theme_minimal()

3. Perbandingan dengan Regresi Linear

3.1. Fit model linear sederhana

fit_lm <- lm(circumference ~ age, data = Orange)
summary(fit_lm)
## 
## Call:
## lm(formula = circumference ~ age, data = Orange)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -46.310 -14.946  -0.076  19.697  45.111 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 17.399650   8.622660   2.018   0.0518 .  
## age          0.106770   0.008277  12.900 1.93e-14 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 23.74 on 33 degrees of freedom
## Multiple R-squared:  0.8345, Adjusted R-squared:  0.8295 
## F-statistic: 166.4 on 1 and 33 DF,  p-value: 1.931e-14
# GOF untuk linear
pred_lm <- predict(fit_lm, newdata = Orange)
SSE_lm <- sum((Orange$circumference - pred_lm)^2)
SST <- sum((Orange$circumference - mean(Orange$circumference))^2)
R2_lm <- 1 - SSE_lm / SST
AIC_lm <- AIC(fit_lm)

tibble(model = "Linear", SSE = SSE_lm, R2 = R2_lm, AIC = AIC_lm)
## # A tibble: 1 × 4
##   model     SSE    R2   AIC
##   <chr>   <dbl> <dbl> <dbl>
## 1 Linear 18595. 0.835  325.

3.2. Bandingkan metrik (SSE, R², AIC)

gof_table <- bind_rows(
  Linear = tibble(SSE = SSE_lm, R2 = R2_lm, AIC = AIC_lm),
  Logistic = gof_logis %>% rename(R2 = R2_pseudo),
  Asymptotic = gof_asymp %>% rename(R2 = R2_pseudo),
  .id = "model"
)

gof_table
## # A tibble: 3 × 5
##   model         SSE    R2   AIC     SST
##   <chr>       <dbl> <dbl> <dbl>   <dbl>
## 1 Linear     18595. 0.835  325.     NA 
## 2 Logistic   17480. 0.844  325. 112366.
## 3 Asymptotic 18335. 0.837  326. 112366.

3.3. Visualisasi semua model dalam satu plot

Orange_plot2 <- Orange_plot %>%
  mutate(pred_lm = pred_lm)

ggplot(Orange_plot2, aes(x = age, y = circumference)) +
  geom_point(aes(color = factor(Tree))) +
  geom_line(aes(y = pred_lm), size = 1, linetype = "dotdash") +
  geom_line(aes(y = pred_logis), size = 1, linetype = "dashed") +
  geom_line(aes(y = pred_asymp), size = 1, linetype = "solid") +
  labs(title = "Perbandingan Model: Linear (dotdash), Logistic (dashed), Asymptotic (solid)", x = "Age", y = "Circumference") +
  theme_minimal()

3.4. Diskusi

  • Pertumbuhan melambat → model nonlinear lebih realistis.
  • SSE lebih kecil dan R² lebih besar pada model nonlinear.
  • Parameter biologis (Asymptotic capacity, titik infleksi) punya arti nyata.

4. Simulasi: Pertumbuhan Eksponensial

4.1. Model & simulasi

set.seed(123)
A_true <- 2
b_true <- 0.6
sigma <- 0.5

t <- seq(0, 5, by = 0.2)
y_true <- A_true * exp(b_true * t)
y_obs <- y_true + rnorm(length(t), mean = 0, sd = sigma)
dat_sim <- tibble(t = t, y = y_obs, y_true = y_true)

ggplot(dat_sim, aes(x = t, y = y)) +
  geom_point() +
  geom_line(aes(y = y_true), linetype = "dashed") +
  labs(title = "Simulasi: Pertumbuhan Eksponensial dengan Noise", x = "Time", y = "Observasi y") +
  theme_minimal()

4.2. Estimasi parameter

lin_start <- lm(log(pmax(y, .0001)) ~ t, data = dat_sim)
A_start <- exp(coef(lin_start)[1])
b_start <- coef(lin_start)[2]

fit_exp <- nls(y ~ A * exp(b * t), data = dat_sim, start = list(A = A_start, b = b_start))
summary(fit_exp)
## 
## Formula: y ~ A * exp(b * t)
## 
## Parameters:
##   Estimate Std. Error t value Pr(>|t|)    
## A 2.073357   0.056813   36.49   <2e-16 ***
## b 0.589045   0.006321   93.19   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.4407 on 24 degrees of freedom
## 
## Number of iterations to convergence: 2 
## Achieved convergence tolerance: 4.297e-07
coef(fit_exp)
##         A         b 
## 2.0733568 0.5890452

4.3. Goodness-of-fit

pred_sim <- predict(fit_exp, newdata = dat_sim)
SSE_sim <- sum((dat_sim$y - pred_sim)^2)
SST_sim <- sum((dat_sim$y - mean(dat_sim$y))^2)
R2_sim <- 1 - SSE_sim / SST_sim

tibble(SSE = SSE_sim, R2 = R2_sim)
## # A tibble: 1 × 2
##     SSE    R2
##   <dbl> <dbl>
## 1  4.66 0.998
dat_sim <- dat_sim %>% mutate(pred = pred_sim)

ggplot(dat_sim, aes(x = t)) +
  geom_point(aes(y = y)) +
  geom_line(aes(y = y_true), linetype = "dashed") +
  geom_line(aes(y = pred), linetype = "solid") +
  labs(title = "Hasil Fit: Model Eksponensial pada Data Simulasi", y = "y") +
  theme_minimal()

5. Kesimpulan

Berdasarkan hasil analisis yang telah dilakukan, dapat disimpulkan bahwa model nonlinear memiliki kemampuan yang jauh lebih baik dalam menjelaskan dinamika pertumbuhan dibandingkan dengan model linear sederhana. Pada studi data nyata menggunakan dataset Orange, model nonlinear (misalnya logistic maupun asymptotic) menunjukkan nilai SSE yang lebih rendah dan R² pseudo yang lebih tinggi dibandingkan model linear. Hal ini menegaskan bahwa pola pertumbuhan yang bersifat melambat pada usia lebih tua tidak dapat ditangkap oleh regresi linear, tetapi dapat diakomodasi dengan baik oleh model nonlinear yang memiliki bentuk kurva sesuai dengan mekanisme biologis pertumbuhan.

Selain itu, parameter-parameter yang dihasilkan oleh model nonlinear juga memberikan informasi yang lebih bermakna secara biologis. Misalnya, parameter Asym menunjukkan kapasitas pertumbuhan maksimum yang dapat dicapai, sedangkan xmid atau lrc berkaitan dengan titik percepatan atau laju pertumbuhan. Interpretasi ini sangat penting bagi penelitian biologi, pertanian, maupun ekonomi, karena memberikan pemahaman tentang batasan dan dinamika suatu sistem.

Pada bagian simulasi dengan data pertumbuhan eksponensial, metode nls() terbukti mampu mengestimasi parameter dasar (A dan b) dengan nilai yang mendekati parameter sebenarnya, meskipun data terkontaminasi oleh noise. Hal ini memperlihatkan bahwa regresi nonlinear cukup andal dalam mengidentifikasi pola dasar pertumbuhan, asalkan diberikan tebakan awal parameter yang memadai. Goodness-of-fit pada simulasi juga menunjukkan hasil yang sangat baik dengan nilai R² pseudo yang tinggi.

Secara keseluruhan, analisis ini menegaskan bahwa regresi nonlinear merupakan pendekatan yang lebih sesuai dalam konteks data pertumbuhan, baik untuk studi nyata maupun simulasi. Model linear memang dapat digunakan sebagai pendekatan awal, namun keterbatasannya sangat jelas terlihat ketika data menunjukkan kurva pertumbuhan yang kompleks. Oleh karena itu, penggunaan model nonlinear sangat direkomendasikan dalam penelitian dan praktik yang berkaitan dengan analisis pertumbuhan biologis maupun fenomena ekonomi yang serupa.