<p>It looks like you came from one of my previous answer in 2016: <a href="https://stackoverflow.com/a/40113075/4891738">mgcv: How to set number and / or locations of knots for splines</a>, borrowing my code snippet:</p>
<pre><code>my_knots &lt;- myfit$smooth[[1]]$xp
plot(x, y, col= &quot;grey&quot;, main = &quot;my knots&quot;);
lines(x, myfit$linear.predictors, col = 2, lwd = 2)
abline(v = my_knots, lty = 2)
</code></pre>
<p>In that answer, my demonstration was made with cubic regression spline (<code>bs = 'cr'</code>), where knot placement is simple to do. But for B-splines, things are more complicated. So take this answer as a complement to that answer.</p>
<hr />
<p>For B-spline classes in <strong>mgcv</strong>, i.e., <code>'bs'</code> being &quot;bs&quot; (<code>?b.spline</code>), &quot;ps&quot; (<code>?p.spline</code>) or &quot;ad&quot; (<code>?adaptive.smooth</code>), the argument <code>k</code> is the number of B-splines, not the number of knots. And the first take-home message is: <strong>the number of B-splines is NOT equal to the number of knots.</strong></p>
<p>Knot placement for B-splines is a dirty work. Usually you only specify <code>k</code> and <strong>mgcv</strong> will place knots automatically for you (see for example, <a href="https://stackoverflow.com/q/37379609/4891738">Extract knots, basis, coefficients and predictions for P-splines in adaptive smooth</a>). If you want to control knot placement yourself, the number of knots you provide must be compatible with <code>k</code>. This can cause great confusion if you don't well understand B-splines.</p>
<p>I highly recommend your reading the Appendix (page 33-34) of one of my work: <a href="https://arxiv.org/pdf/2201.06808.pdf" rel="nofollow noreferrer">General P-splines for Non-uniform B-splines</a>, to know some fundamental stuff of B-splines. Make sure you understand what are the <strong>domain</strong>, <strong>interior knots</strong> and <strong>auxiliary boundary knots</strong>. In the following, I will just show you how to use these knowledge to write the correct code.</p>
<hr />
<p>Here is how to place knots for your example.</p>
<pre><code>## degree of spline
deg &lt;- 3

## domain
a &lt;- min(x)
#[1] 5.86
b &lt;- max(x)
#[1] 24.16

## interior knots (must be between a and b)
xs &lt;- c(6, 20)
#[1]  6 20

## domain knots
xd &lt;- c(a, xs, b)
#[1]  5.86  6.00 20.00 24.16

## clamped auxiliary boundary knots
left.aux &lt;- rep(a, deg)
#[1] 5.86 5.86 5.86
right.aux &lt;- rep(b, deg)
#[1] 24.16 24.16 24.16

## complete B-spline knots
my.knots &lt;- c(left.aux, xd, right.aux)
#[1]  5.86  5.86  5.86  5.86  6.00 20.00 24.16 24.16 24.16 24.16
</code></pre>
<p>Here is how to specify <code>k</code> for your example.</p>
<pre><code>my.k &lt;- length(xs) + deg + 1
#[1] 6
</code></pre>
<p>Now we can work with <strong>mgcv</strong>.</p>
<pre><code>myfit &lt;- gam(y ~ s(x, bs = 'bs', k = my.k),
             knots = list(x = my.knots))
#Family: gaussian 
#Link function: identity
#
#Formula:
#y ~ s(x, bs = &quot;bs&quot;, k = my.k, m = deg)
#
#Estimated degrees of freedom:
#3.81  total = 4.81
</code></pre>
<p>The knots you passed in are stored here (which agree with <code>my.knots</code>):</p>
<pre><code>## For B-spline classes, knots are stored in $knots instead of $xp
myfit$smooth[[1]]$knots
#[1]  5.86  5.86  5.86  5.86  6.00 20.00 24.16 24.16 24.16 24.16
</code></pre>
<hr />
<p>Accompanying <a href="https://arxiv.org/pdf/2201.06808.pdf" rel="nofollow noreferrer">General P-splines for Non-uniform B-splines</a> are R packages <strong>gps</strong> and <strong>gps.mgcv</strong>. The latter package introduces a new &quot;gps&quot; class to <strong>mgcv</strong>, where <code>bs = 'ps'</code> and <code>bs = 'bs'</code> are special cases of <code>bs = 'gps'</code>. The new &quot;gps&quot; class makes knot placement easier, because it automatically places auxiliary boundary knots for you and you only need to provide interior knots.</p>
<pre><code>## The package stays on GitHub for the moment
## but will be on CRAN in the future.
## You may need to first install package 'devtools' from CRAN.
devtools::install_github(&quot;ZheyuanLi/gps&quot;)
devtools::install_github(&quot;ZheyuanLi/gps.mgcv&quot;)
</code></pre>
<pre><code>library(gps.mgcv)

## as same as using 'bs = 'bs''
myfit &lt;- gam(y ~ s(x, bs = 'gps', k = my.k, xt = list(derivative = TRUE)),
             knots = list(x = xs))  ## provide interior knots

## the novel general P-spline
gpsfit &lt;- gam(y ~ s(x, bs = 'gps', k = my.k),
             knots = list(x = xs))  ## provide interior knots
</code></pre>
<p>Construction information (domain, interior knots, etc) are stored in <code>myfit$smooth[[1]]$xt</code> and <code>gpsfit$smooth[[1]]$xt</code>.</p>
Fitting a smooth spline (GAM function) in R: Error in number of knots required to fit spline -- knot requirements increasing
<p>I'm trying to fit a smooth spline to what looks like data with two peaks. First, I fit a smooth spline to my data to identify the potential position of the knots.</p>
<pre><code>library(npreg)
library(splines)
library(mgcv)

x &lt;- c(20.70, 20.44, 20.58, 21.02, 19.90,  6.20,  8.20,  6.92,  5.86,  6.44,  6.34,  8.48,  8.46,  9.00,  9.06,  9.00,  9.06, 17.98, 18.42, 19.18, 22.88, 24.16,20.20, 23.50)

y &lt;- c(19.884208, 12.772114, 12.932944,  5.016790, 11.405843,  3.310724,  3.950049,  3.641571,  4.073783,  4.616096,  3.425635,  7.773548,  7.498084, 9.474213,  6.162779, 11.041210, 12.618555,  6.287967,  4.286919,  3.242361,  7.571644,  3.379709,  5.274434,  8.8258)


data = data.frame(x,y)

fit_spline &lt;- smooth.spline(x,y)
plot(x,y)
lines(fit_spline,lwd=2,col=&quot;purple&quot;)
</code></pre>
<p><a href="https://i.stack.imgur.com/DMkPJ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/DMkPJ.png" alt="enter image description here" /></a></p>
<p>Then, I wanted to run a regression using the gam function where I can specify the position of the knots. I get an error that says <code>Error in smooth.construct.bs.smooth.spec(object, dk$data, dk$knots) : there should be  7  supplied knots</code> I am not sure where it's drawing this number. If I supply 7 knots, it says it needs 13 knots...and the same erorr gets repeated. I am unclear on how to proceed.</p>
<pre><code>myfit &lt;- gam(y ~ s(x, bs = 'bs', k = 3),
             knots = list(x = c(1,5,20)))

my_knots &lt;- myfit$smooth[[1]]$xp
plot(x, y, col= &quot;grey&quot;, main = &quot;my knots&quot;);
lines(x, myfit$linear.predictors, col = 2, lwd = 2)
abline(v = my_knots, lty = 2)
</code></pre>