hans glick hans glick - 2 months ago 13
R Question

Naming elements of a nested list from their index in R

I got this nested list :

dico <- list(list(list(c("dim.", "dimension", "dimensions", "mesures"
), c("45 cm", "45", "45 CM", "0.45m")), list(c("tamano", "volumen",
"dimension", "talla"), c("45 cm", "45", "0.45 M", "45 centimiento"
)), list(c("measures", "dimension", "measurement"), c("45 cm",
"0.45 m", "100 inches", "100 pouces"))), list(list(c("poids",
"poid", "poids net"), c("100 grammes", "100 gr", "100")), list(
c("peso", "carga", "peso especifico"), c("100 gramos", "100g",
"100", "100 g")), list(c("weight", "net wieght", "weight (grammes)"
), c("100 grams", "100", "100 g"))), list(list(c("Batterie oui/non",
"batterie", "présence batterie"), c("Oui", "batterie", "OUI"
)), list(c("bateria", "bateria si or no", "bateria disponible"
), c("si", "bateria furnindo", "1")), list(c("Battery available",
"battery", "battery yes or no"), c("yes", "Y", "Battery given"
))))

[[1]]
[[1]][[1]]
[[1]][[1]][[1]]
[1] "dim." "dimension" "dimensions" "mesures"

[[1]][[1]][[2]]
[1] "45 cm" "45" "45 CM" "0.45m"


What I want is to create a list with the same structure but instead of having the original values, I want to have a sort of "index" name like :

[[1]]
[[1]][[1]]
[[1]][[1]][[1]]
[1] "1|1|1|1" "1|1|1|2" "1|1|1|3" "1|1|1|4"

[[1]][[1]][[2]]
[1] "1|1|2|1" "1|1|2|2" "1|1|2|3" "1|1|2|4"


and so forth ...

Of course the number of elements is not constant through the different nested indexes. Anyone know how to do that? I heard about rapply but I could not make it.

Answer

We can use melt (from reshape2) to convert the nested list to a data.frame with the index columns ('L1', 'L2', 'L3') and the 'value' column, convert it to data.table (setDT(...)), grouped by 'L1', 'L2', 'L3', we get the sequence of rows (1:.N), paste the elements of the rows with do.call to a single vector, then relist it to a list with the same structure as that of 'dico' by specifying the skeleton.

library(data.table)
library(reshape2)
dico2 <- relist(do.call(paste, c(setDT(melt(dico))[, 1:.N ,
          by =  .(L1, L2, L3)], sep="|")), skeleton = dico)
dico2
#[[1]]
#[[1]][[1]]
#[[1]][[1]][[1]]
#[1] "1|1|1|1" "1|1|1|2" "1|1|1|3" "1|1|1|4"

#[[1]][[1]][[2]]
#[1] "1|1|2|1" "1|1|2|2" "1|1|2|3" "1|1|2|4"

#...

#[[3]][[3]]
#[[3]][[3]][[1]]
#[1] "3|3|1|1" "3|3|1|2" "3|3|1|3"

#[[3]][[3]][[2]]
#[1] "3|3|2|1" "3|3|2|2" "3|3|2|3"
Comments