Wybierz pierwszy element listy zagnieżdżonej


86

Powiedzmy, że mam taką listę:

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

Chciałbym mieć listę zawierającą tylko pierwsze elementy zagnieżdżonej listy. Mogę to zrobić, zwracając inną taką listę

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

Czy jest do tego notacja skrótowa?

Odpowiedzi:


137

Niewielki skrót, ale możesz to zrobić:

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

1
Zgadzam się, że wygląda fajniej. Miałem nadzieję, że będzie to krótszy sposób, ale zdecyduję się na fajniejszy!
Alex,

@ A5C1D2H2I1M1N2O1R2T1 Doceniam czystość i zwięzłość, ale czy możesz wyjaśnić „[[”? Nie znalazłem nic przydatnego w? Lapply
Mehrad Mahmoudian

2
@MehradMahmoudian, lepszym miejscem do wyszukania byłoby „extract” ( stat.ethz.ch/R-manual/R-devel/library/base/html/Extract.html ).
A5C1D2H2I1M1N2O1R2T1

43

Inna możliwość wykorzystuje fajną purrrbibliotekę:

library(purrr)
map(x, 1)

5
Dla tych, którzy się zastanawiają, działa to, ponieważ mapinterpretuje wartości liczbowe jako wyodrębnianie, na przykład[[
qwr

11

Na przykładową listę możesz po prostu zrobić:

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

ale to zależy od tego, czy każda podlista ma dokładnie 2 elementy.

Jeśli istnieje różna liczba elementów, możesz najpierw sapplyobliczyć długości, a następnie obliczyć odpowiadające im pozycje pierwszego elementu (zobacz cumsum), a następnie wybrać te wartości z unlistlisty ed. Ale do tego czasu przyjęta odpowiedź jest prawdopodobnie znacznie prostsza.

Jeśli wszystkie listy podrzędne mają tę samą długość (ale mogą różnić się od 2), możesz zrobić coś takiego:

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

lub jakiś inny rzut na wspólny obiekt. Ale wątpię, czy byłoby to tak skuteczne, jak to lapplypodejście.


2

Możemy użyć, pluckz rvestktórego wybiera pierwszy element z każdej zagnieżdżonej listy

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

#[[2]]
#[1] 3

#[[3]]
#[1] 5

Zauważ, że to daje inny wynik ze pluckz purrrktórych wybiera 1st elementu ( x[[1]])

purrr::pluck(x, 1)

#[[1]]
#[1] 1

#[[2]]
#[1] 2

0

Niezupełnie krótka notacja, ale można to również zrobić za pomocą spasowania:

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

# [[1]]
# [1] 1
# 
# [[2]]
# [1] 3
# 
# [[3]]
# [1] 5
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.