Seleziona il primo elemento dell'elenco nidificato


88

Diciamo che ho una lista come questa:

x = list(list(1,2), list(3,4), list(5,6))

Vorrei una lista che contenga solo i primi elementi della lista annidata. Posso farlo restituendo un altro elenco in questo modo

x1 = lapply(x, function(l) l[[1]])

C'è una notazione scorciatoia per questo?

Risposte:


144

Non è una scorciatoia, ma puoi farlo:

lapply(x, `[[`, 1)
# [[1]]
# [1] 1
#
# [[2]]
# [1] 3
#
# [[3]]
# [1] 5

1
Sono d'accordo che sembra più bello. Speravo che ci sarebbe stato un modo più breve per farlo, ma mi accontenterò di un modo più interessante!
Alex

@ A5C1D2H2I1M1N2O1R2T1 Apprezzo la pulizia e la brevità, ma puoi spiegare il "[["? Non ho trovato niente di utile in? Lapply
Mehrad Mahmoudian

2
@MehradMahmoudian, un posto migliore in cui guardare sarebbe "extract" ( stat.ethz.ch/R-manual/R-devel/library/base/html/Extract.html ).
A5C1D2H2I1M1N2O1R2T1

44

Un'altra possibilità utilizza la simpatica purrrlibreria:

library(purrr)
map(x, 1)

5
Per coloro che si stanno chiedendo, questo funziona poiché mapinterpreta i valori numerici come estrazione, come[[
qwr

12

Per il tuo elenco di esempio puoi semplicemente fare:

unlist(x)[ c(TRUE,FALSE) ]

ma questo dipende dal fatto che ogni sottolista abbia esattamente 2 elementi.

Se ci sono diversi numeri di elementi, puoi prima fare un sapplyper calcolare le lunghezze, quindi calcolare le corrispondenti posizioni del primo elemento (vedi cumsum), quindi selezionare quei valori dall'elenco unlisted. Ma a quel punto la risposta accettata è probabilmente molto più semplice.

Se tutte le sottoliste hanno la stessa lunghezza (ma potrebbero essere diverse da 2), potresti fare qualcosa del tipo:

do.call( rbind, x)[,1]

o qualche altro cast su un oggetto comune. Ma dubito che questo sarebbe efficiente quanto l' lapplyapproccio.


3

Possiamo usare pluckda rvestcui seleziona il primo elemento da ogni elenco annidato

rvest::pluck(x, 1)
#[[1]]
#[1] 1

#[[2]]
#[1] 3

#[[3]]
#[1] 5

Si noti che questo dà risultato diverso con pluckda purrrcui seleziona 1 ° elemento ( x[[1]])

purrr::pluck(x, 1)

#[[1]]
#[1] 1

#[[2]]
#[1] 2

0

Non esattamente una breve notazione, ma questo può essere fatto anche con una piega:

Reduce(function(a, b) c(a, b[1]), x, init = c()) 

# [[1]]
# [1] 1
# 
# [[2]]
# [1] 3
# 
# [[3]]
# [1] 5
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.