Yeah, predicting modify-in-place is hard (it's pretty rare); that example may be flawed given current R internals.
A more consistent example is in data.table, which works really hard to make sure it modifies in-place as much as possible (so as to be fast). Note the difference between base R and data.table:
df <- data.frame(x = 1:3)
lobstr::obj_addr(df)
#> [1] "0x7f8652344bf0"
lobstr::obj_addr(df$x)
#> [1] "0x7f8653d834b8"
df$x[[3]] <- 4L
lobstr::obj_addr(df)
#> [1] "0x7f8653959880"
lobstr::obj_addr(df$x)
#> [1] "0x7f8652fae988"
library(data.table)
dt <- data.table(x = 1:3)
lobstr::obj_addr(dt)
#> [1] "0x7f8652596400"
lobstr::obj_addr(dt$x)
#> [1] "0x7f8652e380c8"
dt[3, x := 4L]
lobstr::obj_addr(dt)
#> [1] "0x7f8652596400"
lobstr::obj_addr(dt$x)
#> [1] "0x7f8652e380c8"