I tried to replace some elements in list a with another elements B1 or B2 in R. That uses function f to generate a new list c. However, when I manually replace the elements by creating a list d, the new list c is different from d, even though both look the same.
a <- list(~X1, ~X2 + C1 + X1*C1)
b <- list(~X1, ~X2 + X3)
f <- \(nms, replacement) {
replacement <- paste0(replacement, seq_along(nms))
Map(\(nms, replacement) {
vars <- all.vars(nms)
setNames(lapply(rep(replacement, length(vars)), as.name), vars)
}, nms, replacement) |>
unlist()
}
c <- lapply(a, \(x) do.call(substitute, list(x, f(b, "B"))))
d <- list(~B1, ~B2 + C1 + B1*C1)
When I check if c and d are identical, it returns that they are not the same:
identical(c,d)
[1] FALSE
But I can't find where the different elements lie in
c[!c %in% d]
list()
I am very confused about what the different elements are. By directly looking at c and d, they seem to be the same. I really need to keep function f to do the element replacement, but have to ensure c and d are essentially the same.
A follow-up question, the reason why the previous problem is concerning is because, if I use list c to draw a matrix, it will fail. But if I use d, manually created list, it works.
B1 <- rnorm(100)
B2 <- rnorm(100, mean = 2)
C1 <- rbinom(100, size = 1, prob = 0.5)
data <- data.frame(cbind(B1, B2, C1))
model.matrix(d[[2]], model.frame(d[[2]], data, na.action = 'na.pass'))
model.matrix(c[[2]], model.frame(c[[2]], data, na.action = 'na.pass'))
Error in x$terms %||% attr(x, "terms") %||% stop("no terms component nor attribute") : no terms component nor attribute
This error message was incurred from list c, but for list d, no error occurred.
They're not identical but they are 'equal', so there's no difference to find, e.g.
a <- list(~X1, ~X2 + C1 + X1*C1)
b <- list(~X1, ~X2 + X3)
f <- \(nms, replacement) {
replacement <- paste0(replacement, seq_along(nms))
Map(\(nms, replacement) {
vars <- all.vars(nms)
setNames(lapply(rep(replacement, length(vars)), as.name), vars)
}, nms, replacement) |>
unlist()
}
c <- lapply(a, \(x) do.call(substitute, list(x, f(b, "B"))))
d <- list(~B1, ~B2 + C1 + B1*C1)
identical(c,d)
#> [1] FALSE
str(c)
#> List of 2
#> $ : language ~B1
#> $ : language ~B2 + C1 + B1 * C1
str(d)
#> List of 2
#> $ :Class 'formula' language ~B1
#> .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv>
#> $ :Class 'formula' language ~B2 + C1 + B1 * C1
#> .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv>
all.equal(c,d)
#> [1] TRUE
Created on 2024-09-09 with reprex v2.1.0
The difference highlighted by str()
is causing your issue with model.matrix()
(in the 'follow up' section). If you pass c[[2]]
as a formula it works as expected, e.g.
a <- list(~X1, ~X2 + C1 + X1*C1)
b <- list(~X1, ~X2 + X3)
f <- \(nms, replacement) {
replacement <- paste0(replacement, seq_along(nms))
Map(\(nms, replacement) {
vars <- all.vars(nms)
setNames(lapply(rep(replacement, length(vars)), as.name), vars)
}, nms, replacement) |>
unlist()
}
c <- lapply(a, \(x) do.call(substitute, list(x, f(b, "B"))))
d <- list(~B1, ~B2 + C1 + B1*C1)
identical(c,d)
#> [1] FALSE
str(c)
#> List of 2
#> $ : language ~B1
#> $ : language ~B2 + C1 + B1 * C1
str(d)
#> List of 2
#> $ :Class 'formula' language ~B1
#> .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv>
#> $ :Class 'formula' language ~B2 + C1 + B1 * C1
#> .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv>
all.equal(c,d)
#> [1] TRUE
B1 <- rnorm(100)
B2 <- rnorm(100, mean = 2)
C1 <- rbinom(100, size = 1, prob = 0.5)
data <- data.frame(cbind(B1, B2, C1))
model.matrix(d[[2]], model.frame(d[[2]], data, na.action = 'na.pass'))
#> (Intercept) B2 C1 B1 C1:B1
#> 1 1 3.093556617 1 -0.78860541 -0.78860541
#> 2 1 1.886026799 0 0.56973224 0.00000000
#> 3 1 2.673870066 1 -0.60595212 -0.60595212
#> 4 1 1.871221289 0 -0.94427123 0.00000000
#> 5 1 0.921999097 0 -1.69236771 0.00000000
#> 6 1 2.075295923 1 0.10612483 0.10612483
#> 7 1 2.460368025 1 1.27639862 1.27639862
#> 8 1 4.009522227 0 0.39725422 0.00000000
#> 9 1 2.223665025 1 -0.67107557 -0.67107557
#> 10 1 3.618806953 1 0.21343146 0.21343146
#> 11 1 3.307040111 1 -1.25317583 -1.25317583
#> 12 1 3.941725053 0 -0.69040161 0.00000000
#> 13 1 3.111269308 1 0.55712532 0.55712532
#> 14 1 2.132800352 1 0.79852880 0.79852880
#> 15 1 1.454812161 1 0.18188305 0.18188305
#> 16 1 4.326464313 1 -0.11846250 -0.11846250
#> 17 1 1.302022850 0 -0.87418884 0.00000000
#> 18 1 0.583680486 1 -0.53905498 -0.53905498
#> 19 1 0.635689127 0 1.19463088 0.00000000
#> 20 1 3.054064555 0 0.54188247 0.00000000
#> 21 1 1.539410493 1 1.52761448 1.52761448
#> 22 1 3.674028603 0 0.37046407 0.00000000
#> 23 1 3.700911590 1 0.67188467 0.67188467
#> 24 1 2.634141310 0 0.57403657 0.00000000
#> 25 1 2.966272829 1 0.30644870 0.30644870
#> 26 1 2.332830222 1 0.32473422 0.32473422
#> 27 1 1.540861739 1 1.40447120 1.40447120
#> 28 1 -0.940790234 0 1.69992443 0.00000000
#> 29 1 3.290360051 1 0.09498966 0.09498966
#> 30 1 2.650609034 0 0.77487189 0.00000000
#> 31 1 2.303463420 0 1.53959759 0.00000000
#> 32 1 1.053506147 0 0.73908997 0.00000000
#> 33 1 1.426712923 0 -0.16465926 0.00000000
#> 34 1 -0.201379101 0 -0.38726197 0.00000000
#> 35 1 0.001141829 0 -0.58938402 0.00000000
#> 36 1 0.375382810 1 1.26362046 1.26362046
#> 37 1 1.206842118 0 -0.61859053 0.00000000
#> 38 1 1.834290474 1 -0.42452583 -0.42452583
#> 39 1 0.846476578 1 -1.81057200 -1.81057200
#> 40 1 1.330010557 1 0.34031947 0.34031947
#> 41 1 2.124938389 1 -1.12457154 -1.12457154
#> 42 1 2.023037941 1 1.32196017 1.32196017
#> 43 1 2.129205146 0 -0.95367504 0.00000000
#> 44 1 4.724999255 0 -0.36177523 0.00000000
#> 45 1 3.487162408 1 1.11070383 1.11070383
#> 46 1 2.553726607 0 0.69837652 0.00000000
#> 47 1 3.050741904 0 -0.67757336 0.00000000
#> 48 1 3.554602933 0 0.36333151 0.00000000
#> 49 1 2.748949526 0 0.87355033 0.00000000
#> 50 1 1.026679772 1 1.14239462 1.14239462
#> 51 1 1.345758771 1 -1.32579950 -1.32579950
#> 52 1 3.360090558 1 -0.99770094 -0.99770094
#> 53 1 3.150835981 0 -0.91257389 0.00000000
#> 54 1 3.217728895 1 -0.77698461 -0.77698461
#> 55 1 2.312442115 0 0.27581649 0.00000000
#> 56 1 0.699403756 1 1.94805079 1.94805079
#> 57 1 0.770966838 1 1.47982081 1.47982081
#> 58 1 1.211283624 1 0.40359669 0.40359669
#> 59 1 3.251803657 1 0.40494923 0.40494923
#> 60 1 0.558543700 0 -0.33612244 0.00000000
#> 61 1 2.339337168 1 0.78301829 0.78301829
#> 62 1 1.558130647 0 -1.15495472 0.00000000
#> 63 1 2.790130444 1 -1.35876495 -1.35876495
#> 64 1 1.337390342 0 0.17752648 0.00000000
#> 65 1 1.033420092 0 -2.29789756 0.00000000
#> 66 1 -0.321807848 1 -1.93711695 -1.93711695
#> 67 1 1.958510332 1 -0.63353430 -0.63353430
#> 68 1 2.281820149 0 -1.08199237 0.00000000
#> 69 1 3.035093868 1 0.26209777 0.26209777
#> 70 1 2.851736534 1 -0.56065301 -0.56065301
#> 71 1 2.007729850 0 0.23194564 0.00000000
#> 72 1 2.155800998 0 0.62628023 0.00000000
#> 73 1 1.162590867 0 0.81750230 0.00000000
#> 74 1 1.721310695 0 -1.28561868 0.00000000
#> 75 1 2.839788378 0 -0.86662818 0.00000000
#> 76 1 2.059912681 0 -1.89798538 0.00000000
#> 77 1 2.282398919 1 1.73596974 1.73596974
#> 78 1 2.565795767 1 -0.12856807 -0.12856807
#> 79 1 2.572737178 0 -0.51742529 0.00000000
#> 80 1 0.533060826 0 1.01470751 0.00000000
#> 81 1 2.303617594 0 0.08326794 0.00000000
#> 82 1 2.710917777 0 -2.59741216 0.00000000
#> 83 1 1.397209217 1 -2.37363088 -2.37363088
#> 84 1 2.140376061 1 -0.90394275 -0.90394275
#> 85 1 1.391443923 0 -0.99545878 0.00000000
#> 86 1 2.697787502 1 1.31235291 1.31235291
#> 87 1 1.070710761 1 -0.32742765 -0.32742765
#> 88 1 1.725460871 0 -0.20906359 0.00000000
#> 89 1 2.245153738 1 -0.48761022 -0.48761022
#> 90 1 0.987976417 0 1.04495976 0.00000000
#> 91 1 0.230881185 1 -0.26202523 -0.26202523
#> 92 1 2.751294035 0 0.42203115 0.00000000
#> 93 1 2.023670252 1 0.21725446 0.21725446
#> 94 1 2.508597779 0 -0.34738879 0.00000000
#> 95 1 1.682285681 0 -0.44146421 0.00000000
#> 96 1 1.584391454 1 1.93577488 1.93577488
#> 97 1 1.831828815 0 -1.09342683 0.00000000
#> 98 1 1.657436050 0 0.44482820 0.00000000
#> 99 1 2.378333477 0 -0.44507681 0.00000000
#> 100 1 2.959965426 1 0.03676946 0.03676946
#> attr(,"assign")
#> [1] 0 1 2 3 4
str(d[[2]])
#> Class 'formula' language ~B2 + C1 + B1 * C1
#> ..- attr(*, ".Environment")=<environment: R_GlobalEnv>
model.matrix(c[[2]], model.frame(c[[2]], data, na.action = 'na.pass'))
#> Error in x$terms %||% attr(x, "terms") %||% stop("no terms component nor attribute"): no terms component nor attribute
str(c[[2]])
#> language ~B2 + C1 + B1 * C1
model.matrix(as.formula(c[[2]]), model.frame(c[[2]], data, na.action = 'na.pass'))
#> (Intercept) B2 C1 B1 C1:B1
#> 1 1 3.093556617 1 -0.78860541 -0.78860541
#> 2 1 1.886026799 0 0.56973224 0.00000000
#> 3 1 2.673870066 1 -0.60595212 -0.60595212
#> 4 1 1.871221289 0 -0.94427123 0.00000000
#> 5 1 0.921999097 0 -1.69236771 0.00000000
#> 6 1 2.075295923 1 0.10612483 0.10612483
#> 7 1 2.460368025 1 1.27639862 1.27639862
#> 8 1 4.009522227 0 0.39725422 0.00000000
#> 9 1 2.223665025 1 -0.67107557 -0.67107557
#> 10 1 3.618806953 1 0.21343146 0.21343146
#> 11 1 3.307040111 1 -1.25317583 -1.25317583
#> 12 1 3.941725053 0 -0.69040161 0.00000000
#> 13 1 3.111269308 1 0.55712532 0.55712532
#> 14 1 2.132800352 1 0.79852880 0.79852880
#> 15 1 1.454812161 1 0.18188305 0.18188305
#> 16 1 4.326464313 1 -0.11846250 -0.11846250
#> 17 1 1.302022850 0 -0.87418884 0.00000000
#> 18 1 0.583680486 1 -0.53905498 -0.53905498
#> 19 1 0.635689127 0 1.19463088 0.00000000
#> 20 1 3.054064555 0 0.54188247 0.00000000
#> 21 1 1.539410493 1 1.52761448 1.52761448
#> 22 1 3.674028603 0 0.37046407 0.00000000
#> 23 1 3.700911590 1 0.67188467 0.67188467
#> 24 1 2.634141310 0 0.57403657 0.00000000
#> 25 1 2.966272829 1 0.30644870 0.30644870
#> 26 1 2.332830222 1 0.32473422 0.32473422
#> 27 1 1.540861739 1 1.40447120 1.40447120
#> 28 1 -0.940790234 0 1.69992443 0.00000000
#> 29 1 3.290360051 1 0.09498966 0.09498966
#> 30 1 2.650609034 0 0.77487189 0.00000000
#> 31 1 2.303463420 0 1.53959759 0.00000000
#> 32 1 1.053506147 0 0.73908997 0.00000000
#> 33 1 1.426712923 0 -0.16465926 0.00000000
#> 34 1 -0.201379101 0 -0.38726197 0.00000000
#> 35 1 0.001141829 0 -0.58938402 0.00000000
#> 36 1 0.375382810 1 1.26362046 1.26362046
#> 37 1 1.206842118 0 -0.61859053 0.00000000
#> 38 1 1.834290474 1 -0.42452583 -0.42452583
#> 39 1 0.846476578 1 -1.81057200 -1.81057200
#> 40 1 1.330010557 1 0.34031947 0.34031947
#> 41 1 2.124938389 1 -1.12457154 -1.12457154
#> 42 1 2.023037941 1 1.32196017 1.32196017
#> 43 1 2.129205146 0 -0.95367504 0.00000000
#> 44 1 4.724999255 0 -0.36177523 0.00000000
#> 45 1 3.487162408 1 1.11070383 1.11070383
#> 46 1 2.553726607 0 0.69837652 0.00000000
#> 47 1 3.050741904 0 -0.67757336 0.00000000
#> 48 1 3.554602933 0 0.36333151 0.00000000
#> 49 1 2.748949526 0 0.87355033 0.00000000
#> 50 1 1.026679772 1 1.14239462 1.14239462
#> 51 1 1.345758771 1 -1.32579950 -1.32579950
#> 52 1 3.360090558 1 -0.99770094 -0.99770094
#> 53 1 3.150835981 0 -0.91257389 0.00000000
#> 54 1 3.217728895 1 -0.77698461 -0.77698461
#> 55 1 2.312442115 0 0.27581649 0.00000000
#> 56 1 0.699403756 1 1.94805079 1.94805079
#> 57 1 0.770966838 1 1.47982081 1.47982081
#> 58 1 1.211283624 1 0.40359669 0.40359669
#> 59 1 3.251803657 1 0.40494923 0.40494923
#> 60 1 0.558543700 0 -0.33612244 0.00000000
#> 61 1 2.339337168 1 0.78301829 0.78301829
#> 62 1 1.558130647 0 -1.15495472 0.00000000
#> 63 1 2.790130444 1 -1.35876495 -1.35876495
#> 64 1 1.337390342 0 0.17752648 0.00000000
#> 65 1 1.033420092 0 -2.29789756 0.00000000
#> 66 1 -0.321807848 1 -1.93711695 -1.93711695
#> 67 1 1.958510332 1 -0.63353430 -0.63353430
#> 68 1 2.281820149 0 -1.08199237 0.00000000
#> 69 1 3.035093868 1 0.26209777 0.26209777
#> 70 1 2.851736534 1 -0.56065301 -0.56065301
#> 71 1 2.007729850 0 0.23194564 0.00000000
#> 72 1 2.155800998 0 0.62628023 0.00000000
#> 73 1 1.162590867 0 0.81750230 0.00000000
#> 74 1 1.721310695 0 -1.28561868 0.00000000
#> 75 1 2.839788378 0 -0.86662818 0.00000000
#> 76 1 2.059912681 0 -1.89798538 0.00000000
#> 77 1 2.282398919 1 1.73596974 1.73596974
#> 78 1 2.565795767 1 -0.12856807 -0.12856807
#> 79 1 2.572737178 0 -0.51742529 0.00000000
#> 80 1 0.533060826 0 1.01470751 0.00000000
#> 81 1 2.303617594 0 0.08326794 0.00000000
#> 82 1 2.710917777 0 -2.59741216 0.00000000
#> 83 1 1.397209217 1 -2.37363088 -2.37363088
#> 84 1 2.140376061 1 -0.90394275 -0.90394275
#> 85 1 1.391443923 0 -0.99545878 0.00000000
#> 86 1 2.697787502 1 1.31235291 1.31235291
#> 87 1 1.070710761 1 -0.32742765 -0.32742765
#> 88 1 1.725460871 0 -0.20906359 0.00000000
#> 89 1 2.245153738 1 -0.48761022 -0.48761022
#> 90 1 0.987976417 0 1.04495976 0.00000000
#> 91 1 0.230881185 1 -0.26202523 -0.26202523
#> 92 1 2.751294035 0 0.42203115 0.00000000
#> 93 1 2.023670252 1 0.21725446 0.21725446
#> 94 1 2.508597779 0 -0.34738879 0.00000000
#> 95 1 1.682285681 0 -0.44146421 0.00000000
#> 96 1 1.584391454 1 1.93577488 1.93577488
#> 97 1 1.831828815 0 -1.09342683 0.00000000
#> 98 1 1.657436050 0 0.44482820 0.00000000
#> 99 1 2.378333477 0 -0.44507681 0.00000000
#> 100 1 2.959965426 1 0.03676946 0.03676946
#> attr(,"assign")
#> [1] 0 1 2 3 4
Created on 2024-09-09 with reprex v2.1.0
You could also evaluate the call, e.g. eval(c[[2]])
will give you the same output as as.formula(c[[2]])
. Does that help with your use-case?