Konwertować kolumnę data.frame na wektor?


163

Mam ramkę danych taką jak:

a1 = c(1, 2, 3, 4, 5)
a2 = c(6, 7, 8, 9, 10)
a3 = c(11, 12, 13, 14, 15)
aframe = data.frame(a1, a2, a3)

Próbowałem wykonać następujące czynności, aby przekonwertować jedną z kolumn na wektor, ale to nie działa:

avector <- as.vector(aframe['a2'])
class(avector) 
[1] "data.frame"

To jedyne rozwiązanie, jakie mogłem wymyślić, ale zakładam, że musi być lepszy sposób na zrobienie tego:

class(aframe['a2']) 
[1] "data.frame"
avector = c()
for(atmp in aframe['a2']) { avector <- atmp }
class(avector)
[1] "numeric"

Uwaga: moje słownictwo powyżej może być wyłączone, więc popraw mnie, jeśli tak. Wciąż uczę się świata R.Dodatkowo każde wyjaśnienie tego, co się tutaj dzieje, jest mile widziane (np. Odnoszące się do Pythona lub innego języka pomogłyby!)


5
Jak widzisz w odpowiedziach, dokładna lektura ?'[.data.frame'zabierze Cię bardzo daleko.
joran

Odpowiedzi:


208

Spróbuję to wyjaśnić bez popełniania błędów, ale założę się, że spowoduje to wyjaśnienie lub dwa w komentarzach.

Ramka danych to lista. Kiedy podzbirujesz ramkę danych przy użyciu nazwy kolumny i [, otrzymujesz podlistę (lub pod ramkę danych). Jeśli chcesz rzeczywistą kolumnę atomową, możesz użyć [[lub nieco myląco (dla mnie) możesz zrobićaframe[,2] która zwraca wektor, a nie podlistę.

Spróbuj więc uruchomić tę sekwencję, a może wszystko będzie jaśniejsze:

avector <- as.vector(aframe['a2'])
class(avector) 

avector <- aframe[['a2']]
class(avector)

avector <- aframe[,2]
class(avector)

6
+1 To jest przydatne. Przyzwyczaiłem się do używania aframe[,"a2"]ze względu na możliwość używania tego zarówno z ramkami danych, jak i macierzami i wydaje się, że otrzymuję te same wyniki - wektor.
Iterator

8
[..., drop = F]zawsze zwróci ramkę danych
hadley,

1
Warto o tym wiedzieć, ponieważ df$xskładnia zwraca wektor. Używałem tej składni przez długi czas, ale kiedy musiałem zacząć używać df['name']lub df[n]pobierać kolumny, napotkałem problemy, gdy próbowałem wysłać je do funkcji, które oczekiwały wektorów. Używanie df[[n]]lub df[['x']]wyjaśnianie rzeczy.
rensa

8
Dlaczego as.vectorwydaje się, że po cichu nie ma żadnego efektu? Czy to nie powinno albo zwrócić wektora, albo wyraźnie zawieść?
bli

aframe[['a2']]jest bardzo przydatny w przypadku sfobiektów, ponieważ aframe[,"a2"]zwróci dwie kolumny, ponieważ zawiera kolumnę geometrii.
Matt


32

Możesz użyć $ekstrakcji:

class(aframe$a1)
[1] "numeric"

lub podwójny nawias kwadratowy:

class(aframe[["a1"]])
[1] "numeric"

21

Nie potrzebujesz as.vector(), ale potrzebujesz poprawnego indeksowania:avector <- aframe[ , "a2"]

Należy pamiętać o drop=FALSEmożliwości [:

R> aframe <- data.frame(a1=c1:5, a2=6:10, a3=11:15)
R> aframe
  a1 a2 a3
1  1  6 11
2  2  7 12
3  3  8 13
4  4  9 14
5  5 10 15
R> avector <- aframe[, "a2"]
R> avector
[1]  6  7  8  9 10
R> avector <- aframe[, "a2", drop=FALSE]
R> avector
  a2
1  6
2  7
3  8
4  9
5 10
R> 

4
+1: Przypomnienie drop=FALSEjest przydatne - pomaga mi to w przypadkach, gdy mogę wybrać N kolumn z data.frame, w tych przypadkach, gdy N = 1.
Iterator

Używam tego, gdy nie mogę przewidzieć liczby wybranych kolumn, aw przypadku pojawienia się jednej kolumny wynik nadal jest przekazywany jako data.frame z n kolumnami. Wektor może rzucić małpią klucz do funkcji w dół wiersza.
Roman Luštrik,

11

Kolejną zaletą stosowania operatora „[[” jest to, że działa on zarówno z danymi.frame, jak i data.table. Więc jeśli funkcja ma być uruchomiona zarówno dla data.frame, jak i data.table, a chcesz wyodrębnić z niej kolumnę jako wektor, to

data[["column_name"]] 

jest najlepszy.


8

Możesz spróbować czegoś takiego-

as.vector(unlist(aframe$a2))

Jest to dobre, jeśli chcesz porównać dwie kolumny za pomocą identical.
p-robot

5

Jeśli użyjesz tylko operatora wyodrębniania, zadziała. Domyślnie [] ustawia opcję drop=TRUE, której chcesz tutaj. Zobacz, ?'['aby uzyskać więcej informacji.

>  a1 = c(1, 2, 3, 4, 5)
>  a2 = c(6, 7, 8, 9, 10)
>  a3 = c(11, 12, 13, 14, 15)
>  aframe = data.frame(a1, a2, a3)
> aframe[,'a2']
[1]  6  7  8  9 10
> class(aframe[,'a2'])
[1] "numeric"


3
a1 = c(1, 2, 3, 4, 5)
a2 = c(6, 7, 8, 9, 10)
a3 = c(11, 12, 13, 14, 15)
aframe = data.frame(a1, a2, a3)
avector <- as.vector(aframe['a2'])

avector<-unlist(avector)
#this will return a vector of type "integer"

2

Używam list do filtrowania ramek danych według tego, czy mają wartość% w% a lista.

Tworzyłem listy ręcznie, eksportując 1-kolumnową ramkę danych do programu Excel, gdzie dodawałem „” wokół każdego elementu, przed wklejeniem do R: list <- c („el1”, „el2”, ...), co zwykle było po którym następuje FilteredData <- podzbiór (Dane,% kolumny w% listy).

Po przeszukaniu stackoverflow i nie znalezieniu intuicyjnego sposobu konwertowania 1-kolumnowej ramki danych na listę, publikuję teraz mój pierwszy wkład w stackoverflow:

# assuming you have a 1 column dataframe called "df"
list <- c()
for(i in 1:nrow(df)){
  list <- append(list, df[i,1])
}
View(list)
# This list is not a dataframe, it is a list of values
# You can filter a dataframe using "subset([Data], [Column] %in% list")

1

Możemy również ogólnie przekonwertować kolumny data.frame na prosty wektor. as.vectorto za mało, gdyż zachowuje klasę i strukturę data.frame, więc musimy też wyciągnąć pierwszy (i jedyny) element:

df_column_object <- aframe[,2]
simple_column <- df_column_object[[1]]

Wszystkie proponowane do tej pory rozwiązania wymagają zakodowania tytułów kolumn na sztywno. To czyni je niepogólnymi (wyobraź sobie, że stosujesz to do argumentów funkcji).

Alternatywnie możesz oczywiście najpierw przeczytać nazwy kolumn z kolumny, a następnie wstawić je do kodu w innych rozwiązaniach.

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.