R语言seq()函数排序问题:绘制按数据框顺序拟合的平滑线
Hey there! I get your frustration—let's fix this plotting issue step by step.
The Root of the Problem
Your current code generates xl as a sequence sorted by the numerical value of DECA (from smallest to largest). When you use this sorted xl to predict and draw the line, R plots the curve left-to-right along the x-axis, regardless of the original order of points in your data frame. But what you want is a smooth line that follows the order of the points as they appear in your data (like the path of your transect), not the sorted x-values.
Solution: Plot Smooth Line Along Data Frame Order
Here's how to adjust your code to get the exact result you want:
Step 1: Add a Sequence Column to Track Row Order
First, we'll create a column that represents the order of rows in your data frame—this lets us fit a model that follows the transect path, not just the x-axis values.
# Add a column for row sequence (1 to number of rows) testtransect2$row_seq <- 1:nrow(testtransect2)
Step 2: Fit Loess to the Sequence, Not DECA
We'll use this row sequence as the independent variable for our loess model, so the fit follows the order of your data points:
# Fit loess model using row sequence to capture transect order loess_model <- loess(TOTAL ~ row_seq, data = testtransect2, span = 0.25)
Step 3: Generate Dense Sequence for Smoothness
Create a more dense sequence of row numbers to get a smooth, continuous line:
# Generate 1000 evenly spaced points along the row sequence dense_seq <- seq(min(testtransect2$row_seq), max(testtransect2$row_seq), length.out = 1000)
Step 4: Predict Values and Map Back to DECA
We need to predict both the smoothed TOTAL values and their corresponding DECA positions along the dense sequence:
# Predict smoothed TOTAL values pred_total <- predict(loess_model, newdata = data.frame(row_seq = dense_seq)) # Interpolate DECA values for the dense sequence (matches the transect path) pred_deca <- approx(x = testtransect2$row_seq, y = testtransect2$DECA, xout = dense_seq)$y
Step 5: Plot the Results
Now draw your scatter plot and the smooth line that follows the data order:
# Draw the original scatter plot plot(testtransect2$DECA, testtransect2$TOTAL, asp = 1) # Add the smooth line that follows your transect path lines(pred_deca, pred_total)
Alternative: Use Smooth Spline for Simpler Code
If you prefer a more concise approach, you can use smooth.spline to directly fit a curve along the row order:
plot(testtransect2$DECA, testtransect2$TOTAL, asp = 1) # Fit spline to row sequence and TOTAL spline_fit <- smooth.spline(x = 1:nrow(testtransect2), y = testtransect2$TOTAL, spar = 0.25) # Interpolate DECA values for the spline fit pred_deca_spline <- approx(x = 1:nrow(testtransect2), y = testtransect2$DECA, xout = spline_fit$x)$y # Draw the smooth line lines(pred_deca_spline, spline_fit$y)
Either method will produce a smooth line that follows the order of points in your data frame, just like the example you shared!
内容的提问来源于stack exchange,提问作者arnaud

