Reputation: 533
I'm trying to use lapply on a list of sublists. However all I can manage is overwriting the sublists with what should be going into them, rather than writing into the sublists.
To make my problem clear to the point of tedium, this would be the same as having a 'Shops List', with 'DIY Store' and 'Gardening Store'. Trying to write 'Hammer and Nails' into the DIY sublist and 'Seeds' into the Gardening sublist, but realising you actually scrawled all your items into 'Shopping List', destroying your sublists.
I imagine there is a simple way to tell R "whoa there, just recursively look at my first layer of sublists". In the hope that this is a simple fix and the wider context isn't overly helpful, my lapply section and where I would think the change should be made, is just below.
# Create a list of Types and the matrices
StatMatrices <- lapply(Types, function(q) {
# Select Versus List so that for example, a HESH list only contains HESHVersusHEAT<
# HESHVerusHESH, HESHVersusAPDS and HESHVersusAPDR, and not HEATVersus.. and so on...
WhichVersus <- grep(paste0("(^", q, ")"), VersusList, value = T, perl = T)
EmptySublist <- (setNames(vector("list", length(Types)), WhichVersus))
})
names(StatMatrices) <- Types
Now I have tried a few things like doubling up the lapply
, but I'm not even sure I'm doing it correcly, let alone if it's the correct solution.
# Create a list of Types and the matrices
StatMatrices <- lapply(Types,
lapply, function(q) {
# Select Versus List so that for example, a HESH list only contains HESHVersusHEAT<
# HESHVerusHESH, HESHVersusAPDS and HESHVersusAPDR, and not HEATVersus.. and so on...
WhichVersus <- grep(paste0("(^", q, ")"), VersusList, value = T, perl = T)
EmptySublist <- (setNames(vector("list", length(Types)), WhichVersus))
})
names(StatMatrices) <- Types
My full code is shown below. I've tried to comment it but essentially I have 4 'Types', and I'm creating a lists called StatMatrices
. This will contain further lists, the next layer will consist of names such as e.g. VelStatMatrices
, names according to the subsequent information that will be stored in them. The next set of lists will be the so called Types (i.e. HEAT
,HESH
,APDS
and APCR
). These will contain comparison matrices, though for now are only place holder names. Thus inside HESH
you will have HESHVersusHEAT
HESHVerusHESH
, HESHVersusAPDS
and HESHVersusAPDR
waiting to be filled with a matrix.
A final list path would look something like this:
StatMatrices[["VelStatMatrices"]][[HESH]][[HESHVerusHEAT]]
and another like this
StatMatrices[["PenStatMatrices"]][["APDS"]][["APDSVerusHESH"]]
Here is what I have so far:
#Mun Types
Types = c("HEAT", "HESH", "APDS", "APCR")
#Create empty vector for Versus name strings
VersusList <- c()
#Create Versus names e.g. HEATVerusAPDS and APCRVersusHESH etc
for (q in 1:length(Types)) {
for (j in 1:length(Types)) {
# VersusList(i) <- paste0(Types[q], "Versus", Types[j])
VersusList <- c(VersusList, paste0(Types[q], "Versus", Types[j]))
}
}
#Create List of lists of stat matrices, each to be filled with matrices,
StatMatrices <- list("PenStatMatrices", "DmgStatMatrices", "VelStatMatrices")
# Create a list of Types and the matrices
StatMatrices <- lapply(Types, function(q) {
# Select Versus List so that for example, a HESH list only contains HESHVersusHEAT<
# HESHVerusHESH, HESHVersusAPDS and HESHVersusAPDR, and not HEATVersus.. and so on...
WhichVersus <- grep(paste0("(^", q, ")"), VersusList, value = T, perl = T)
EmptySublist <- (setNames(vector("list", length(Types)), WhichVersus))
})
names(StatMatrices) <- Types
I'm only just starting to use lapply and hardly know what I'm doing with R so any help would be appreciated.
Upvotes: 1
Views: 542
Reputation: 2737
Sorry for not providing a more concrete answer at this point (maybe a bit more concise question would help) but I would recommend to look at utils::modifyList()
. It seems like that could help.
Also, looking at your use case, you may save yourself a bit of pain structuring objects a bit differently, one example is a matrix of matrices:
Make a 4x4 matrix of 4x4 matrices (of random numbers for show):
mtr <- matrix(
rep(list(matrix(runif(16L), nrow = 4L)), 16L),
nrow = 4,
ncol = 4
)
Set the row and col names for better readability
rownames(mtr) <- colnames(mtr) <- c("HEAT", "HESH", "APDS", "APCR")
And then accessing the data like so:
mtr["HEAT", "HEAT"]
which gives
[[1]]
[,1] [,2] [,3] [,4]
[1,] 0.413062588 0.2497092 0.6465910 0.9492033
[2,] 0.007168949 0.9049881 0.1491240 0.1494439
[3,] 0.540454187 0.4837212 0.2674728 0.6261278
[4,] 0.327341522 0.9747880 0.7509647 0.5489474
And you have a list of matrices, so you can easily apply functions:
lapply(mtr, summary)
Returning (truncated):
[[1]]
V1 V2 V3 V4
Min. :0.007169 Min. :0.2497 Min. :0.1491 Min. :0.1494
1st Qu.:0.247298 1st Qu.:0.4252 1st Qu.:0.2379 1st Qu.:0.4491
Median :0.370202 Median :0.6944 Median :0.4570 Median :0.5875
Mean :0.322007 Mean :0.6533 Mean :0.4535 Mean :0.5684
3rd Qu.:0.444910 3rd Qu.:0.9224 3rd Qu.:0.6727 3rd Qu.:0.7069
Max. :0.540454 Max. :0.9748 Max. :0.7510 Max. :0.9492
[[2]]
V1 V2 V3 V4
Min. :0.007169 Min. :0.2497 Min. :0.1491 Min. :0.1494
1st Qu.:0.247298 1st Qu.:0.4252 1st Qu.:0.2379 1st Qu.:0.4491
...
Upvotes: 1