1

I have some data which looks like:

# A tibble: 100 × 5
   purchase_price provincia     municipio                                   distrito         zona                              
            <dbl> <chr>         <chr>                                       <chr>            <chr>                             
 1         207000 Gipuzkoa      Bajo Bidasoa                                Irun             Pinar - Anaka - Belaskoenea       
 2          65000 Valencia      Valencia, Zona de                           Valencia Capital Els Orriols                       
 3          62000 Valencia      Valencia, Zona de                           Valencia Capital Barrio de Benicalap               
 4         200000 Valencia      Valencia, Zona de                           Valencia Capital Barrio de Benimaclet              
 5         293000 Málaga        Costa del Sol Occidental - Zona de Estepona Estepona         Parque Central                    
 6          80000 Araba - Álava Laguardia - Rioja Alavesa                   Navaridas        NA                                
 7          96500 Tarragona     Tarragonès                                  Salou            Mar i Camp - Platja dels Capellans

I would like to group_by and list the data.

data %>% 
  group_by(provincia, municipio, distrito, zona) %>% 
  list()

Where the expected output would be nested lists.

Using the example, the expected output will be:

list(
  "Valencia" = list(
    "Valencia, Zona de" = list(
      "Valencia Capital" = list(
        "Es Orriols",
        "Barrio de Benicalap",
        "Barrio de Benimaclet"
      ) # no more items in the municipio "Valencia"
    )
  ),
  "Tarragona" = list(
    "Tarragonès" = list(
      "Salou" = list(
        "Mar i Camp - Platja dels Capellans",
        "Platja de Llevant"
      )
    )
  )
)


$Valencia
$Valencia$`Valencia, Zona de`
$Valencia$`Valencia, Zona de`$`Valencia Capital`
$Valencia$`Valencia, Zona de`$`Valencia Capital`[[1]]
[1] "Es Orriols"

$Valencia$`Valencia, Zona de`$`Valencia Capital`[[2]]
[1] "Barrio de Benicalap"

$Valencia$`Valencia, Zona de`$`Valencia Capital`[[3]]
[1] "Barrio de Benimaclet"




$Tarragona
$Tarragona$Tarragonès
$Tarragona$Tarragonès$Salou
$Tarragona$Tarragonès$Salou[[1]]
[1] "Mar i Camp - Platja dels Capellans"

$Tarragona$Tarragonès$Salou[[2]]
[1] "Platja de Llevant"

SO, Provincia >= municipio >= distrito >= zona (The first list is the provincias, the first nested list is the municipio, the second nested list is the distrito and the final nested list is the zona (where can obtain NAs)

Data

data <- structure(list(purchase_price = c(207000, 65000, 62000, 2e+05, 
293000, 80000, 96500, 119500, 149999, 144000, 298000, 135000, 
310000, 285000, 269000, 120000, 595000, 355000, 96000, 490000, 
195000, 235000, 197000, 70000, 215000, 169000, 124900, 195000, 
185000, 190000, 390348, 113500, 295000, 299995, 156000, 195000, 
185000, 260000, 370000, 180000, 105000, 249000, 390000, 295000, 
86999, 219900, 264999, 56800, 179900, 150000, 145000, 168500, 
160000, 180000, 168000, 42300, 119000, 350000, 390000, 110000, 
420000, 154000, 429000, 85000, 259000, 495000, 170000, 102490, 
469000, 245000, 138000, 127000, 1390000, 320000, 420000, 292000, 
87500, 120000, 475000, 170000, 61000, 255000, 49000, 226000, 
220000, 3e+05, 30000, 265000, 330000, 220000, 220000, 139000, 
880000, 75000, 220000, 76400, 150000, 46000, 25000, 170000), 
    provincia = c("Gipuzkoa", "Valencia", "Valencia", "Valencia", 
    "Málaga", "Araba - Álava", "Tarragona", "Jaén", "Tarragona", 
    "Barcelona", "Barcelona", "Alicante", "Granada", "Málaga", 
    "Barcelona", "Tarragona", "Tarragona", "Barcelona", "Valencia", 
    "Tarragona", "Castellón", "Segovia", "Alicante", "Tarragona", 
    "Málaga", "Girona", "Cantabria", "Barcelona", "Barcelona", 
    "Barcelona", "Barcelona", "Sevilla", "Granada", "Barcelona", 
    "Barcelona", "Cáceres", "Barcelona", "Valencia", "Gipuzkoa", 
    "Santa Cruz de Tenerife", "Tarragona", "Almería", "Alicante", 
    "Granada", "Tarragona", "Toledo", "Tarragona", "Huelva", 
    "Castellón", "Albacete", "Madrid", "Girona", "Castellón", 
    "Zaragoza", "Madrid", "Alicante", "Barcelona", "Barcelona", 
    "Sevilla", "Castellón", "Valencia", "Málaga", "Alicante", 
    "Lleida", "Girona", "Madrid", "Alicante", "Pontevedra", "Barcelona", 
    "Illes Balears", "Málaga", "A Coruña", "Barcelona", "Barcelona", 
    "Barcelona", "Málaga", "Cádiz", "Valencia", "Barcelona", 
    "Toledo", "Castellón", "Barcelona", "Huelva", "Barcelona", 
    "Tarragona", "A Coruña", "Ciudad Real", "Illes Balears", 
    "Ourense", "Barcelona", "Barcelona", "Málaga", "Málaga", 
    "Córdoba", "Tarragona", "Castellón", "Valencia", "Castellón", 
    "Navarra", "Cádiz"), municipio = c("Bajo Bidasoa", "Valencia, Zona de", 
    "Valencia, Zona de", "Valencia, Zona de", "Costa del Sol Occidental - Zona de Estepona", 
    "Laguardia - Rioja Alavesa", "Tarragonès", "Campiña de Jaén", 
    "Tarragonès", "Maresme", "Maresme", "Marina Baixa", "Vega de Granada", 
    "Costa del Sol Occidental - Zona de Estepona", "Maresme", 
    "Tarragonès", "Tarragonès", "Barcelonès", "Horta Nord", 
    "Tarragonès", "Plana Baixa", "Cuéllar, Zona de", "Alacantí", 
    "Baix Camp", "Costa del Sol Occidental - Zona de Benalmádena", 
    "La Selva", "Costa Oriental", "Vallès Oriental", "Vallès Oriental", 
    "Vallès Oriental", "Maresme", "Sierra Norte", "Vega de Granada", 
    "Vallès Occidental", "Baix Llobregat Sud", "Llanos de Cáceres", 
    "Barcelonès", "La Safor", "Donostialdea - Oarsoldea", "Tenerife", 
    "Tarragonès", "Almería capital y entorno", "Alacantí", 
    "Vega de Granada", "Tarragonès", "Los Montes de Toledo", 
    "Tarragonès", "Huelva capital y entorno", "Plana Alta", 
    "Sierra de Alcaraz - Campo de Montiel", "Zona Sur de Madrid", 
    "La Selva", "Plana Alta", "Zaragoza, Zona de", "Madrid, Zona de", 
    "Vega Baja", "Barcelonès", "Bages", "Sevilla capital y entorno", 
    "Plana Alta", "Valencia, Zona de", "Costa del Sol Occidental - Zona de Estepona", 
    "Marina Alta", "Segrià", "Alt Empordà", "Madrid, Zona de", 
    "Marina Baixa", "Comarca de Vigo", "Vallès Occidental", 
    "Mallorca", "Costa del Sol Occidental - Zona de Estepona", 
    "Comarca de Ferrol", "Vallès Occidental", "Osona", "Osona", 
    "Costa del Sol Occidental - Zona de Estepona", "La Janda", 
    "Ribera Alta (Valencia)", "Osona", "Toledo, Zona de", "Plana Alta", 
    "Osona", "Huelva capital y entorno", "Vallès Oriental", 
    "Baix Penedès", "Comarca de Ferrol", "Alcudia (Ciudad Real)", 
    "Mallorca", "Comarca de Ourense", "Vallès Occidental", "Vallès Occidental", 
    "Costa del Sol Occidental - Zona de Estepona", "Málaga capital y entorno", 
    "La Subbética", "Baix Penedès", "Plana Alta", "Valencia, Zona de", 
    "Plana Baixa", "Comarca de Pamplona", "Campiña de Jerez"
    ), distrito = c("Irun", "Valencia Capital", "Valencia Capital", 
    "Valencia Capital", "Estepona", "Navaridas", "Salou", "Marmolejo", 
    "Salou", "Mataró", "Dosrius", "Benidorm", "Granada Capital", 
    "Manilva", "Dosrius", "Roda de Berà", "Roda de Berà", "Barcelona Capital", 
    "Puig", "Tarragona Capital", "Vila-real", "Marugán", "San Vicente del Raspeig / Sant Vicent del Raspeig", 
    "Mont-roig del Camp", "Benalmádena", "Anglès", "Laredo", 
    "Granollers", "Granollers", "Granollers", "Cabrils", "El Ronquillo", 
    "Cenes de la Vega", "Santa Perpètua de Mogoda", "Sant Boi de Llobregat", 
    "Cáceres Capital", "Barcelona Capital", "Barx", "Donostia - San Sebastián", 
    "Tacoronte", "Salou", "Almería Capital", "El Campello", 
    "Albolote", "Salou", "Nambroca", "Salou", "Huelva Capital", 
    "Castellón de la Plana / Castelló de la Plana", "Alcaraz", 
    "Fuenlabrada", "Riells i Viabrea", "Castellón de la Plana / Castelló de la Plana", 
    "Zaragoza Capital", "Madrid Capital", "Torrevieja", "Badalona", 
    "Castellgalí", "Sevilla Capital", "Cabanes", "Valencia Capital", 
    "Estepona", "Dénia", "Lleida Capital", "Roses", "Madrid Capital", 
    "L'Alfàs del Pi", "Vigo", "Sabadell", "Palma de Mallorca", 
    "Estepona", "Fene", "Cerdanyola del Vallès", "Vic", "Vic", 
    "Estepona", "Vejer de la Frontera", "Senyera", "Vic", "Toledo Capital", 
    "Borriol", "Santa Eugènia de Berga", "Huelva Capital", "Sant Celoni", 
    "Calafell", "Fene", "Almadén", "Palma de Mallorca", "Ourense Capital", 
    "Terrassa", "Terrassa", "Estepona", "Málaga Capital", "Lucena", 
    "Calafell", "Castellón de la Plana / Castelló de la Plana", 
    "Valencia Capital", "Onda", "Pamplona / Iruña", "Jerez de la Frontera"
    ), zona = c("Pinar - Anaka - Belaskoenea", "Els Orriols", 
    "Barrio de Benicalap", "Barrio de Benimaclet", "Parque Central", 
    NA, "Mar i Camp - Platja dels Capellans", NA, "Platja de Llevant", 
    "Cerdanyola Sud", "Can Massuet del Far", "Levante Alto", 
    "Centro - Sagrario", "Manilva Pueblo", "Canyamars", NA, NA, 
    "Vilapicina i la Torre Llobeta", "El Puig", "Llevant", "Centro", 
    NA, "Centro", "Poble", "Zona Centro Comercial Torrequebrada", 
    NA, "Zona Playa", "Lledoner", "Lledoner", "Lledoner", NA, 
    NA, NA, NA, "Casablanca", "Mejostilla", "El Poble Sec - Parc de Montjuïc", 
    NA, "Amara Zaharra - Arbaizenea", "Campo de Golf - Agua García - Juan Fernández", 
    "Platja de Llevant", "Plaza de Toros - Santa Rita", "Playa Muchavista", 
    NA, "Mar i Camp - Platja dels Capellans", NA, "Centre", "Tres Ventanas", 
    "El Grao", NA, "El Naranjo", NA, "Oeste", "La Magdalena", 
    "Recoletos", "Zona Carrefour - Urbanizaciones", "Sant Roc", 
    NA, "Encarnación - Regina", NA, "Penya - Roja - Avda. Francia", 
    "Bel - Air", "El Montgó", "Mariola", "Centre", "Embajadores - Lavapiés", 
    "Escandinavia - Cautivador", "Casablanca - Calvario", "Creu Alta", 
    "Son Serra - Sa Vileta", "Cancelada", NA, "Bellaterra", "El Sucre - El Nadal", 
    "El Sucre - El Nadal", "Paraiso - Barronal", "Vejer", NA, 
    "El Sucre - El Nadal", "Santa Bárbara", NA, NA, "La Orden", 
    NA, "Segur Platja", NA, NA, "Cala Major", "Centro", "Barri del Centre", 
    "Ca n'Aurell", "Cancelada", "Pinares de San Antón", NA, 
    "Segur Platja", "Norte", "Beteró", NA, "San Juan", "El Rocío - La Milagrosa"
    )), row.names = c(NA, -100L), class = c("tbl_df", "tbl", 
"data.frame"))
Henrik
  • 65,555
  • 14
  • 143
  • 159
user113156
  • 6,761
  • 5
  • 35
  • 81
  • 1
    Related: [Data frame to nested list](https://stackoverflow.com/questions/46407320/data-frame-to-nested-list); [R dataframe to nested list](https://stackoverflow.com/questions/66316828/r-dataframe-to-nested-list); – Henrik Feb 11 '23 at 19:34

2 Answers2

2

I don't know of a really tidy (or easily-extensible) way to do this, but I think this is what you're going for:

str(
  lapply(split(data[,-(1:2)], data[,2]),
         function(prov) {
           lapply(split(prov[,-1], prov[,1]),
                  function(mun) split(mun$zona, mun$distrito))
         })
)
# List of 31
#  $ A Coruna              :List of 1
#   ..$ Comarca de Ferrol:List of 1
#   .. ..$ Fene: chr [1:2] NA NA
#  $ Albacete              :List of 1
#   ..$ Sierra de Alcaraz - Campo de Montiel:List of 1
#   .. ..$ Alcaraz: chr NA
#  $ Alicante              :List of 4
#   ..$ Alacanti    :List of 2
#   .. ..$ El Campello                                      : chr "Playa Muchavista"
#   .. ..$ San Vicente del Raspeig / Sant Vicent del Raspeig: chr "Centro"
#   ..$ Marina Alta :List of 1
#   .. ..$ Denia: chr "El Montgo"
#   ..$ Marina Baixa:List of 2
#   .. ..$ Benidorm      : chr "Levante Alto"
#   .. ..$ L'Alfas del Pi: chr "Escandinavia - Cautivador"
#   ..$ Vega Baja   :List of 1
#   .. ..$ Torrevieja: chr "Zona Carrefour - Urbanizaciones"
### ...

(Note: I still can't get my emacs/ess to do UTF correctly, so I removed all diacritics from your sample data. The process should still work on your real data.)

r2evans
  • 141,215
  • 6
  • 77
  • 149
1

Using an external package, rrapply() (in package rrapply) has a dedication option how = "unmelt" for this purpose:

library(rrapply)

out <- rrapply(data[, c("provincia", "municipio", "distrito", "zona")], how = "unmelt")

str(out, list.len = 5)

#> List of 87
#>  $ Gipuzkoa              :List of 1
#>   ..$ Bajo Bidasoa:List of 1
#>   .. ..$ Irun: chr "Pinar - Anaka - Belaskoenea"
#>  $ Valencia              :List of 1
#>   ..$ Valencia, Zona de:List of 3
#>   .. ..$ Valencia Capital: chr "Els Orriols"
#>   .. ..$ Valencia Capital: chr "Barrio de Benicalap"
#>   .. ..$ Valencia Capital: chr "Barrio de Benimaclet"
#>  $ Málaga                :List of 1
#>   ..$ Costa del Sol Occidental - Zona de Estepona:List of 1
#>   .. ..$ Estepona: chr "Parque Central"
#>  $ Araba - Álava         :List of 1
#>   ..$ Laguardia - Rioja Alavesa:List of 1
#>   .. ..$ Navaridas: chr NA
#>  $ Tarragona             :List of 1
#>   ..$ Tarragonès:List of 1
#>   .. ..$ Salou: chr "Mar i Camp - Platja dels Capellans"
#>   [list output truncated]
Joris C.
  • 5,721
  • 3
  • 12
  • 27