Szukaj…


Składnia

  • data.frame (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, stringsAsFactors = default.stringsAsFactors ())

  • as.data.frame (x, row.names = NULL, opcjonalnie = FALSE, ...) # funkcja ogólna

  • as.data.frame (x, ..., stringsAsFactors = default.stringsAsFactors ()) # Metoda S3 dla klasy „znak”

  • as.data.frame (x, row.names = NULL, opcjonalnie = FALSE, ..., stringsAsFactors = default.stringsAsFactors ()) # Metoda S3 dla klasy „macierz”

  • is.data.frame (x)

Utwórz pustą ramkę danych

Data.frame to specjalny rodzaj listy: jest prostokątny . Każdy element (kolumna) listy ma tę samą długość, a każdy wiersz ma „nazwę wiersza”. Każda kolumna ma swoją klasę, ale klasa jednej kolumny może różnić się od klasy innej kolumny (w przeciwieństwie do macierzy, w której wszystkie elementy muszą mieć tę samą klasę).

Zasadniczo data.frame nie może mieć wierszy ani kolumn:

> structure(list(character()), class = "data.frame")
NULL
<0 rows> (or 0-length row.names)

Ale to niezwykłe. Bardziej typowe jest to, że data.frame ma wiele kolumn i wiele wierszy. Oto ramka danych z trzema wierszami i dwiema kolumnami ( a to klasa numeryczna, a b to klasa znakowa):

> structure(list(a = 1:3, b = letters[1:3]), class = "data.frame")
[1] a b
<0 rows> (or 0-length row.names)

Aby data.frame mogła zostać wydrukowana, będziemy musieli podać niektóre nazwy wierszy. Tutaj używamy tylko liczb 1: 3:

> structure(list(a = 1:3, b = letters[1:3]), class = "data.frame", row.names = 1:3)
  a b
1 1 a
2 2 b
3 3 c

Teraz staje się oczywiste, że mamy ramkę data.frame z 3 wierszami i 2 kolumnami. Możesz to sprawdzić za pomocą nrow() , ncol() i dim() :

> x <- structure(list(a = numeric(3), b = character(3)), class = "data.frame", row.names = 1:3)
> nrow(x)
[1] 3
> ncol(x)
[1] 2
> dim(x)
[1] 3 2

R udostępnia dwie inne funkcje (oprócz structure() ), których można użyć do utworzenia ramki danych. Pierwszy nazywa się intuicyjnie data.frame() . Sprawdza, czy podane nazwy kolumn są prawidłowe, czy elementy listy mają tę samą długość, i podaje niektóre automatycznie generowane nazwy wierszy. Oznacza to, że dane wyjściowe data.frame() mogą teraz zawsze mieć dokładnie to, czego oczekujesz:

> str(data.frame("a a a" = numeric(3), "b-b-b" = character(3)))
'data.frame':   3 obs. of  2 variables:
 $ a.a.a: num  0 0 0
 $ b.b.b: Factor w/ 1 level "": 1 1 1

Druga funkcja nazywa się as.data.frame() . Można tego użyć, aby zmusić obiekt, który nie jest data.frame, do bycia data.frame, uruchamiając go przez data.frame() . Jako przykład rozważmy macierz:

> m <- matrix(letters[1:9], nrow = 3)
> m
     [,1] [,2] [,3]
[1,] "a"  "d"  "g" 
[2,] "b"  "e"  "h" 
[3,] "c"  "f"  "i" 

A wynik:

> as.data.frame(m)
  V1 V2 V3
1  a  d  g
2  b  e  h
3  c  f  i
> str(as.data.frame(m))
'data.frame':   3 obs. of  3 variables:
 $ V1: Factor w/ 3 levels "a","b","c": 1 2 3
 $ V2: Factor w/ 3 levels "d","e","f": 1 2 3
 $ V3: Factor w/ 3 levels "g","h","i": 1 2 3

Podzbiór wierszy i kolumn z ramki danych

Składnia dostępu do wierszy i kolumn: [ , [[ i $

W tym temacie omówiono najczęstszą składnię umożliwiającą dostęp do określonych wierszy i kolumn ramki danych. To są

  • Jak matrix z data[rows, columns] z pojedynczymi nawiasami data[rows, columns]
    • Korzystanie z numerów wierszy i kolumn
    • Używanie nazw kolumn (i wierszy)
  • Jak list :
    • Dane z pojedynczymi nawiasami data[columns] aby uzyskać ramkę danych
    • Z data[[one_column]] podwójnych nawiasach data[[one_column]] aby uzyskać wektor
  • Z $ za dane z jednej kolumny data$column_name

mtcars to wbudowaną mtcars danych mtcars .

Jak macierz: data[rows, columns]

Z indeksami numerycznymi

Korzystając z wbudowanych ramek mtcars , możemy wyodrębnić wiersze i kolumny za pomocą nawiasów [] z przecinkiem. Wskaźniki przed przecinkiem są wierszami:

# get the first row
mtcars[1, ]
# get the first five rows
mtcars[1:5, ]

Podobnie po przecinku są kolumny:

# get the first column
mtcars[, 1]
# get the first, third and fifth columns:
mtcars[, c(1, 3, 5)]

Jak pokazano powyżej, jeśli wiersze lub kolumny pozostaną puste, wszystkie zostaną wybrane. mtcars[1, ] wskazuje pierwszy wiersz ze wszystkimi kolumnami.

Z nazwami kolumn (i wierszy)

Jak dotąd jest to identyczne z dostępem do wierszy i kolumn macierzy. W przypadku data.frame s przez większość czasu lepiej jest używać nazwy kolumny niż indeksu kolumny. Odbywa się to za pomocą character o nazwie kolumny zamiast numeric z numerem kolumny:

# get the mpg column
mtcars[, "mpg"]
# get the mpg, cyl, and disp columns
mtcars[, c("mpg", "cyl", "disp")]

Chociaż rzadziej są używane, nazwy wierszy mogą być również używane:

mtcars["Mazda Rx4", ]

Rzędy i kolumny razem

Argumentów wiersza i kolumny można używać razem:

# first four rows of the mpg column
mtcars[1:4, "mpg"]

# 2nd and 5th row of the mpg, cyl, and disp columns
mtcars[c(2, 5), c("mpg", "cyl", "disp")]

Ostrzeżenie o wymiarach:

Podczas korzystania z tych metod wyodrębnienie wielu kolumn spowoduje odzyskanie ramki danych. Jeśli jednak wyodrębnisz pojedynczą kolumnę, otrzymasz domyślny wektor, a nie ramkę danych.

## multiple columns returns a data frame
class(mtcars[, c("mpg", "cyl")])
# [1] "data.frame"
## single column returns a vector
class(mtcars[, "mpg"])
# [1] "numeric"

Są na to dwa sposoby. Jednym z nich jest traktowanie ramki danych jako listy (patrz poniżej), drugim jest dodanie argumentu drop = FALSE . To mówi R, aby nie „upuszczał nieużywanych wymiarów”:

class(mtcars[, "mpg", drop = FALSE])
# [1] "data.frame"

Zauważ, że macierze działają w ten sam sposób - domyślnie pojedyncza kolumna lub wiersz będzie wektorem, ale jeśli podasz drop = FALSE , możesz zachować go jako macierz z jedną kolumną lub z jednym wierszem.

Jak lista

Ramki danych są zasadniczo list s, tzn. Są listą wektorów kolumn (wszystkie muszą mieć tę samą długość). Listy można podzielić na pojedyncze nawiasy kwadratowe [ dla podlisty lub podwójne nawiasy kwadratowe [[ dla pojedynczego elementu.

Z data[columns] pojedynczych nawiasach data[columns]

Gdy użyjesz pojedynczych nawiasów i bez przecinków, otrzymasz kolumnę z powrotem, ponieważ ramki danych są listami kolumn.

mtcars["mpg"]
mtcars[c("mpg", "cyl", "disp")]
my_columns <- c("mpg", "cyl", "hp")
mtcars[my_columns]
Pojedyncze nawiasy kwadratowe jak lista vs. pojedyncze nawiasy kwadratowe

Różnica między data[columns] a data[, columns] polega na tym, że podczas traktowania data.frame jako list (bez przecinków w nawiasach data.frame ) zwracanym obiektem będzie data.frame . Jeśli użyjesz przecinka do traktowania data.frame jak matrix wówczas wybranie jednej kolumny zwróci wektor, ale wybranie wielu kolumn zwróci data.frame .

## When selecting a single column
## like a list will return a data frame
class(mtcars["mpg"])
# [1] "data.frame"
## like a matrix will return a vector
class(mtcars[, "mpg"])
# [1] "numeric"

Z data[[one_column]] podwójnych nawiasach data[[one_column]]

Aby wyodrębnić pojedynczą kolumnę jako wektor , traktując data.frame jako list , możesz użyć podwójnych nawiasów data.frame [[ . Będzie to działać tylko dla jednej kolumny na raz.

# extract a single column by name as a vector 
mtcars[["mpg"]]

# extract a single column by name as a data frame (as above)
mtcars["mpg"]

Używanie $ aby uzyskać dostęp do kolumn

Pojedynczą kolumnę można wyodrębnić za pomocą magicznego skrótu $ bez użycia cytowanej nazwy kolumny:

# get the column "mpg"
mtcars$mpg

Kolumny dostępne za pomocą $ zawsze będą wektorami, a nie ramkami danych.

Wady $ za dostęp do kolumn

$ Może być wygodnym skrótem, szczególnie jeśli pracujesz w środowisku (takim jak RStudio), które w tym przypadku automatycznie uzupełni nazwę kolumny. Jednak $ ma również wady: używa niestandardowej oceny, aby uniknąć potrzeby cudzysłowów, co oznacza, że nie będzie działać, jeśli nazwa kolumny jest przechowywana w zmiennej.

my_column <- "mpg"
# the below will not work
mtcars$my_column
# but these will work
mtcars[, my_column]  # vector
mtcars[my_column]    # one-column data frame
mtcars[[my_column]]  # vector

Ze względu na te obawy najlepiej zastosować $ w interaktywnych sesjach R, gdy nazwy kolumn są stałe. Do użytku programowego , na przykład podczas pisania funkcji uogólnionej, która będzie używana w różnych zestawach danych o różnych nazwach kolumn, należy unikać $ .

Zauważ też, że domyślnym zachowaniem jest stosowanie częściowego dopasowania tylko podczas wyodrębniania z obiektów rekurencyjnych (z wyjątkiem środowisk) o $

# give you the values of "mpg" column 
# as "mtcars" has only one column having name starting with "m"
mtcars$m 
# will give you "NULL" 
# as "mtcars" has more than one columns having name starting with "d"
mtcars$d

Zaawansowane indeksowanie: indeksy ujemne i logiczne

Ilekroć mamy opcję użycia liczb dla indeksu, możemy również użyć liczb ujemnych, aby pominąć niektóre indeksy lub wektor boolowski (logiczny), aby wskazać dokładnie, które elementy należy zachować.

Wskaźniki ujemne pomijają elementy

mtcars[1, ]   # first row
mtcars[ -1, ] # everything but the first row
mtcars[-(1:10), ] # everything except the first 10 rows

Wektory logiczne wskazują określone elementy, które należy zachować

Możemy użyć warunku takiego jak < aby wygenerować wektor logiczny i wyodrębnić tylko wiersze spełniające warunek:

# logical vector indicating TRUE when a row has mpg less than 15
# FALSE when a row has mpg >= 15
test <- mtcars$mpg < 15 

# extract these rows from the data frame 
mtcars[test, ]

Możemy również ominąć krok zapisywania zmiennej pośredniej

# extract all columns for rows where the value of cyl is 4.
mtcars[mtcars$cyl == 4, ]
# extract the cyl, mpg, and hp columns where the value of cyl is 4
mtcars[mtcars$cyl == 4, c("cyl", "mpg", "hp")]

Funkcje ułatwiające manipulowanie data.frames

Niektóre funkcje data.frames manipulowanie data.frames to subset() , transform() , with() i data.frames within() .

podzbiór

Funkcja subset() pozwala na podzestawienie data.frame w wygodniejszy sposób (podzbiór działa również z innymi klasami):

subset(mtcars, subset = cyl == 6, select = c("mpg", "hp"))
                mpg  hp
Mazda RX4      21.0 110
Mazda RX4 Wag  21.0 110
Hornet 4 Drive 21.4 110
Valiant        18.1 105
Merc 280       19.2 123
Merc 280C      17.8 123
Ferrari Dino   19.7 175

W powyższym kodzie pytamy tylko o linie, w których cyl == 6 oraz o kolumny mpg i hp . Ten sam wynik można osiągnąć za pomocą [] z następującym kodem:

mtcars[mtcars$cyl == 6, c("mpg", "hp")]

przekształcać

Funkcja transform() jest funkcją wygodną do zmiany kolumn wewnątrz data.frame . Na przykład poniższy kod dodaje kolejną kolumnę o nazwie mpg2 z wynikiem mpg^2 do mtcars data.frame :

mtcars <- transform(mtcars, mpg2 = mpg^2)

z i wewnątrz

Zarówno za with() i data.frame within() pozwala oceniać wyrażenia w środowisku data.frame , pozwalając na nieco czystszą składnię, oszczędzając ci użycia $ lub [] .

Na przykład, jeśli chcesz utworzyć, zmienić i / lub usunąć wiele kolumn w airquality data.frame :

aq <- within(airquality, {     
    lOzone <- log(Ozone) # creates new column
    Month <- factor(month.abb[Month]) # changes Month Column
    cTemp <- round((Temp - 32) * 5/9, 1) # creates new column
    S.cT <- Solar.R / cTemp  # creates new column
    rm(Day, Temp) # removes columns
})

Wprowadzenie

Ramy danych są prawdopodobnie strukturą danych, której będziesz najczęściej używać w swoich analizach. Ramka danych jest specjalnym rodzajem listy, która przechowuje wektory tej samej długości różnych klas. Ramki danych tworzy się za pomocą funkcji data.frame . Poniższy przykład pokazuje to, łącząc wektor numeryczny i znakowy w ramkę danych. Wykorzystuje on : operatora, który będzie tworzyć wektor zawierający wszystkie liczby całkowite od 1 do 3.

df1 <- data.frame(x = 1:3, y = c("a", "b", "c"))
df1
##   x y
## 1 1 a
## 2 2 b
## 3 3 c
class(df1)
## [1] "data.frame"

Obiekty ramek danych nie są drukowane ze znakami cudzysłowu, więc klasa kolumn nie zawsze jest oczywista.

df2 <- data.frame(x = c("1", "2", "3"), y = c("a", "b", "c"))
df2
##   x y
## 1 1 a
## 2 2 b
## 3 3 c

Bez dalszego badania nie można rozróżnić kolumn „x” w df1 i df2 . Funkcja str może być używana do opisywania obiektów bardziej szczegółowo niż klasa.

str(df1)
## 'data.frame':    3 obs. of  2 variables:
##  $ x: int  1 2 3
##  $ y: Factor w/ 3 levels "a","b","c": 1 2 3
str(df2)
## 'data.frame':    3 obs. of  2 variables:
##  $ x: Factor w/ 3 levels "1","2","3": 1 2 3
##  $ y: Factor w/ 3 levels "a","b","c": 1 2 3

Tutaj widzisz, że df1 jest data.frame i ma 3 obserwacje 2 zmiennych, „x” i „y”. Następnie powiedziano ci, że „x” ma liczbę całkowitą typu danych (nieistotne dla tej klasy, ale dla naszych celów zachowuje się jak liczba), a „y” jest czynnikiem z trzema poziomami (kolejna klasa danych, o której nie dyskutujemy). Należy zauważyć, że domyślnie ramki danych przymuszają znaki do czynników. Domyślne zachowanie można zmienić za pomocą parametru stringsAsFactors :

df3 <- data.frame(x = 1:3, y = c("a", "b", "c"), stringsAsFactors = FALSE)
str(df3)
## 'data.frame':    3 obs. of  2 variables:
##  $ x: int  1 2 3
##  $ y: chr  "a" "b" "c"

Teraz kolumna „y” jest znakiem. Jak wspomniano powyżej, każda „kolumna” ramki danych musi mieć tę samą długość. Próba utworzenia ramki danych z wektorów o różnych długościach spowoduje błąd. (Spróbuj uruchomić data.frame(x = 1:3, y = 1:4) aby zobaczyć wynikowy błąd.)

Jako przypadki testowe dla ramek danych niektóre dane są domyślnie dostarczane przez R. Jednym z nich jest tęczówka, ładowana w następujący sposób:

mydataframe <- iris
str(mydataframe)

Konwertuj dane przechowywane na liście na pojedynczą ramkę danych za pomocą do.call

Jeśli masz dane zapisane na liście i chcesz przekonwertować tę listę na ramkę danych, funkcja do.call jest łatwym sposobem na osiągnięcie tego. Ważne jest jednak, aby wszystkie elementy listy miały tę samą długość, aby zapobiec niezamierzonemu recyklingowi wartości.

dataList  <- list(1:3,4:6,7:9)  
dataList
# [[1]]
# [1] 1 2 3
#
# [[2]]
# [1] 4 5 6
#
# [[3]]
# [1] 7 8 9

dataframe <- data.frame(do.call(rbind, dataList))
dataframe
#   X1 X2 X3
# 1  1  2  3
# 2  4  5  6
# 3  7  8  9 

Działa również, jeśli twoja lista składa się z samych ramek danych.

dataframeList  <- list(data.frame(a = 1:2, b = 1:2, c = 1:2), 
                       data.frame(a = 3:4, b = 3:4, c = 3:4))
dataframeList
# [[1]]
#   a b c
# 1 1 1 1
# 2 2 2 2

# [[2]]
#   a b c
# 1 3 3 3
# 2 4 4 4

dataframe      <- do.call(rbind, dataframeList)
dataframe
#   a b c
# 1 1 1 1
# 2 2 2 2
# 3 3 3 3
# 4 4 4 4

Konwertuj wszystkie kolumny data.frame na klasę znaków

Częstym zadaniem jest konwersja wszystkich kolumn data.frame na klasę znaków w celu ułatwienia manipulacji, na przykład w przypadku wysyłania data.frame do RDBMS lub scalania data.frame zawierających czynniki, w których poziomy mogą się różnić między danymi wejściowymi. Frame .

Najlepszym momentem na to jest, gdy dane są wczytywane - prawie wszystkie metody wprowadzania danych, które tworzą ramki danych, mają opcje stringsAsFactors które można ustawić na FALSE .

Jeśli dane zostały już utworzone, kolumny czynników można przekonwertować na kolumny znaków, jak pokazano poniżej.

bob <- data.frame(jobs = c("scientist", "analyst"), 
                  pay  = c(160000, 100000), age = c(30, 25))
str(bob)
'data.frame':    2 obs. of  3 variables:
 $ jobs: Factor w/ 2 levels "analyst","scientist": 2 1
 $ pay : num  160000 100000
 $ age : num  30 25
# Convert *all columns* to character
bob[] <- lapply(bob, as.character)
str(bob)
    'data.frame':    2 obs. of  3 variables:
 $ jobs: chr  "scientist" "analyst"
 $ pay : chr  "160000" "1e+05"
 $ age : chr  "30" "25"
# Convert only factor columns to character
bob[] <- lapply(bob, function(x) {
    if is.factor(x) x <- as.character(x)
    return(x)
})

Podzbiór wierszy według wartości kolumny

Wbudowane funkcje mogą dzielić rows columns spełniające warunki.

df <- data.frame(item = c(1:10),
                 price_Elasticity = c(-0.57667, 0.03205, -0.04904, 0.10342, 0.04029, 
                                       0.0742, 0.1669, 0.0313, 0.22204, 0.06158),
                 total_Margin = c(-145062, 98671, 20576, -56382, 207623, 43463, 1235, 
                                   34521, 146553, -74516))

Aby znaleźć rows z price_Elasticity > 0 :

df[df$price_Elasticity > 0, ]

   item price_Elasticity total_Margin
2     2          0.03205        98671
4     4          0.10342       -56382
5     5          0.04029       207623
6     6          0.07420        43463
7     7          0.16690         1235
8     8          0.03130        34521
9     9          0.22204       146553
10   10          0.06158       -74516

podzbiór oparty na price_Elasticity > 0 i total_Margin > 0 :

df[df$price_Elasticity > 0 & df$total_Margin > 0, ]

  item price_Elasticity total_Margin
2    2          0.03205        98671
5    5          0.04029       207623
6    6          0.07420        43463
7    7          0.16690         1235
8    8          0.03130        34521
9    9          0.22204       146553


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow