R Language
Dataframes
Zoeken…
Syntaxis
data.frame (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, stringsAsFactors = default.stringsAsFactors ())
as.data.frame (x, row.names = NULL, optioneel = FALSE, ...) # generieke functie
as.data.frame (x, ..., stringsAsFactors = default.stringsAsFactors ()) # S3-methode voor klasse 'teken'
as.data.frame (x, row.names = NULL, optioneel = FALSE, ..., stringsAsFactors = default.stringsAsFactors ()) # S3-methode voor klasse 'matrix'
is.data.frame (x)
Maak een leeg data.frame
Een data.frame is een speciaal soort lijst: het is rechthoekig . Elk element (kolom) van de lijst heeft dezelfde lengte en elke rij heeft een "rijnaam". Elke kolom heeft zijn eigen klasse, maar de klasse van een kolom kan verschillen van de klasse van een andere kolom (in tegenstelling tot een matrix, waarbij alle elementen dezelfde klasse moeten hebben).
In principe kan een data.frame geen rijen en geen kolommen hebben:
> structure(list(character()), class = "data.frame")
NULL
<0 rows> (or 0-length row.names)
Maar dit is ongebruikelijk. Het komt vaker voor dat een data.frame veel kolommen en veel rijen heeft. Hier is een data.frame met drie rijen en twee kolommen ( a
is een numerieke klasse en b
is een tekenklasse):
> structure(list(a = 1:3, b = letters[1:3]), class = "data.frame")
[1] a b
<0 rows> (or 0-length row.names)
Om het data.frame te kunnen afdrukken, moeten we enkele rijnamen opgeven. Hier gebruiken we alleen de cijfers 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
Nu wordt het duidelijk dat we een data.frame hebben met 3 rijen en 2 kolommen. Je kunt dit controleren met nrow()
, ncol()
en 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 biedt twee andere functies (naast structure()
) die kunnen worden gebruikt om een data.frame te maken. De eerste heet, intuïtief, data.frame()
. Het controleert of de door u opgegeven kolomnamen geldig zijn, dat de lijstelementen allemaal even lang zijn en levert enkele automatisch gegenereerde rijnamen. Dit betekent dat de uitvoer van data.frame()
nu altijd precies is wat u verwacht:
> 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
De andere functie wordt as.data.frame()
. Dit kan worden gebruikt om een object dat geen data.frame is tot een data.frame te dwingen door het door data.frame()
. Overweeg als voorbeeld een matrix:
> m <- matrix(letters[1:9], nrow = 3)
> m
[,1] [,2] [,3]
[1,] "a" "d" "g"
[2,] "b" "e" "h"
[3,] "c" "f" "i"
En het resultaat:
> 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
Rijen en kolommen van een gegevensframe instellen
Syntaxis voor toegang tot rijen en kolommen: [
, [[
en $
Dit onderwerp behandelt de meest voorkomende syntaxis voor toegang tot specifieke rijen en kolommen van een gegevensframe. Dit zijn
- Zoals een
matrix
metdata[rows, columns]
tussen enkele haakjesdata[rows, columns]
- Rij- en kolomnummers gebruiken
- Kolomnamen (en rijen) gebruiken
- Zoals een
list
:- Met enkele haakjes
data[columns]
om een dataframe te krijgen - Met dubbele haakjes
data[[one_column]]
om een vector te krijgen
- Met enkele haakjes
- Met
$
voor een enkele kolomgegevensdata$column_name
We zullen het ingebouwde mtcars
-dataframe gebruiken om dit te illustreren.
Zoals een matrix: data[rows, columns]
Met numerieke indexen
Met behulp van de ingebouwde dataframe mtcars
, kunnen we rijen en kolommen extraheren met behulp van []
haakjes met een komma inbegrepen. Indices vóór de komma zijn rijen:
# get the first row
mtcars[1, ]
# get the first five rows
mtcars[1:5, ]
Evenzo, nadat de komma kolommen bevat:
# get the first column
mtcars[, 1]
# get the first, third and fifth columns:
mtcars[, c(1, 3, 5)]
Zoals hierboven wordt getoond, worden alle rijen geselecteerd als rijen of kolommen leeg zijn. mtcars[1, ]
geeft de eerste rij met alle kolommen aan.
Met kolom- (en rij) namen
Tot nu toe is dit identiek aan hoe rijen en kolommen met matrices worden benaderd. Bij data.frame
s data.frame
meestal de voorkeur om een kolomnaam te gebruiken boven een data.frame
. Dit wordt gedaan door middel van een character
met de naam kolom in plaats van het numeric
met een kolom nummer:
# get the mpg column
mtcars[, "mpg"]
# get the mpg, cyl, and disp columns
mtcars[, c("mpg", "cyl", "disp")]
Hoewel minder gebruikelijk, kunnen rijnamen ook worden gebruikt:
mtcars["Mazda Rx4", ]
Rijen en kolommen samen
De rij- en kolomargumenten kunnen samen worden gebruikt:
# 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")]
Een waarschuwing over dimensies:
Als u bij deze methoden meerdere kolommen extraheert, krijgt u een gegevensframe terug. Als u echter een enkele kolom extraheert, krijgt u een vector en geen gegevensframe onder de standaardopties.
## multiple columns returns a data frame
class(mtcars[, c("mpg", "cyl")])
# [1] "data.frame"
## single column returns a vector
class(mtcars[, "mpg"])
# [1] "numeric"
Er zijn twee manieren om dit te omzeilen. De ene is om het dataframe als een lijst te behandelen (zie hieronder), de andere is om een drop = FALSE
argument toe te voegen. Dit vertelt R om "niet de ongebruikte dimensies te laten vallen":
class(mtcars[, "mpg", drop = FALSE])
# [1] "data.frame"
Merk op dat matrices op dezelfde manier werken - standaard zal een enkele kolom of rij een vector zijn, maar als u drop = FALSE
opgeeft, kunt u deze behouden als een matrix met één kolom of één rij.
Zoals een lijst
Gegevensframes zijn in wezen list
, dwz ze zijn een lijst met kolomvectoren (die allemaal dezelfde lengte moeten hebben). Lijsten kunnen worden gesubset met behulp van enkele haakjes [
voor een sublijst of dubbele haakjes [[
voor een enkel element.
Met enkele haakjes data[columns]
Wanneer u enkele haakjes en geen komma's gebruikt, krijgt u de kolom terug omdat gegevensframes lijsten met kolommen zijn.
mtcars["mpg"]
mtcars[c("mpg", "cyl", "disp")]
my_columns <- c("mpg", "cyl", "hp")
mtcars[my_columns]
Enkele haakjes zoals een lijst versus enkele haakjes zoals een matrix Het verschil tussen data[columns]
en data[, columns]
is dat bij het behandelen van het data.frame
als een list
(geen komma tussen haakjes) het geretourneerde object een data.frame
zal zijn . Als u een komma gebruikt om het data.frame
als een matrix
te behandelen, data.frame
selecteren van een enkele kolom een vector, maar het selecteren van meerdere kolommen data.frame
een 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"
Met dubbele haakjes data[[one_column]]
Om een enkele kolom als een vector te extraheren bij het behandelen van uw data.frame
als een list
, kunt u dubbele haakjes gebruiken [[
. Dit werkt slechts voor één kolom tegelijk.
# 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"]
$
Gebruiken om toegang te krijgen tot kolommen
Een enkele kolom kan worden geëxtraheerd met de magische snelkoppeling $
zonder de naam van een geciteerde kolom:
# get the column "mpg"
mtcars$mpg
Kolommen waartoe toegang wordt verkregen door $
zijn altijd vectoren, geen gegevensframes.
Nadelen van $
voor toegang tot kolommen
De $
kan een handige snelkoppeling zijn, vooral als u in een omgeving (zoals RStudio) werkt die in dit geval de kolomnaam automatisch aanvult. Echter, $
heeft nadelen ook: het maakt gebruik van niet-standaard evaluatie van de noodzaak voor offertes, wat betekent dat het zal niet werken als de naam van uw kolom wordt opgeslagen in een variabele te voorkomen.
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
Vanwege deze zorgen kan $
beste worden gebruikt in interactieve R-sessies wanneer uw kolomnamen constant zijn. Voor programmatisch gebruik, bijvoorbeeld bij het schrijven van een generaliseerbare functie die zal worden gebruikt op verschillende gegevenssets met verschillende kolomnamen, moet $
worden vermeden.
Merk ook op dat het standaardgedrag is om gedeeltelijke overeenkomsten alleen te gebruiken bij het extraheren van recursieve objecten (behalve omgevingen) met $
# 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
Geavanceerde indexering: negatieve en logische indices
Wanneer we de optie hebben om getallen voor een index te gebruiken, kunnen we ook negatieve getallen gebruiken om bepaalde indices of een booleaanse (logische) vector weg te laten om precies aan te geven welke items moeten worden bewaard.
Negatieve indices laten elementen weg
mtcars[1, ] # first row
mtcars[ -1, ] # everything but the first row
mtcars[-(1:10), ] # everything except the first 10 rows
Logische vectoren geven specifieke elementen aan die moeten worden bewaard
We kunnen een voorwaarde zoals <
gebruiken om een logische vector te genereren en alleen de rijen extraheren die aan de voorwaarde voldoen:
# 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, ]
We kunnen ook de stap van het opslaan van de tussenliggende variabele omzeilen
# 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")]
Gemakfuncties om data.frames te manipuleren
Sommige handige functies om data.frames
te manipuleren zijn subset()
, transform()
, with()
en within()
.
subgroep
Met de functie subset()
kunt u een data.frame
op een handigere manier subset (subset werkt ook met andere klassen):
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
In de bovenstaande code vragen we alleen om de regels waarin cyl == 6
en om de kolommen mpg
en hp
. U kunt hetzelfde resultaat bereiken met []
met de volgende code:
mtcars[mtcars$cyl == 6, c("mpg", "hp")]
transformeren
De functie transform()
is een handige functie om kolommen in een data.frame
te wijzigen. De volgende code voegt bijvoorbeeld een andere kolom met de naam mpg2
met het resultaat van mpg^2
aan het mtcars
data.frame
:
mtcars <- transform(mtcars, mpg2 = mpg^2)
met en binnen
Zowel with()
als within()
kunt u uitdrukkingen in de data.frame
omgeving evalueren, waardoor een ietwat schonere syntaxis mogelijk is, waardoor u het gebruik van ongeveer $
of []
kunt besparen.
Bijvoorbeeld, als u wilt maken, wijzigen en / of verwijderen van meerdere kolommen in de 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
})
Invoering
Gegevensframes zijn waarschijnlijk de gegevensstructuur die u het meest zult gebruiken in uw analyses. Een gegevensframe is een speciaal soort lijst waarin vectoren van dezelfde lengte van verschillende klassen worden opgeslagen. U maakt gegevensframes met de functie data.frame
. Het onderstaande voorbeeld laat dit zien door een numerieke en een tekenvector te combineren in een gegevensframe. Het maakt gebruik van de :
operator, die een vector die alle getallen van 1 tot 3 zal leiden.
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"
Gegevenskaderobjecten worden niet afgedrukt met aanhalingstekens, dus de klasse van de kolommen is niet altijd duidelijk.
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
Zonder verder onderzoek kunnen de "x" -kolommen in df1
en df2
niet worden onderscheiden. De str
functie kan worden gebruikt om objecten gedetailleerder te beschrijven dan klasse.
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
Hier zie je dat df1
een data.frame
en 3 observaties heeft van 2 variabelen, "x" en "y". Dan wordt u verteld dat "x" het gegevenstype geheel getal heeft (niet belangrijk voor deze klasse, maar voor onze doeleinden gedraagt het zich als een numeriek) en "y" is een factor met drie niveaus (een andere gegevensklasse die we niet bespreken). Het is belangrijk op te merken dat gegevensframes standaard tekens omzetten in factoren. Het standaardgedrag kan worden gewijzigd met de parameter 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"
Nu is de "y" -kolom een karakter. Zoals hierboven vermeld, moet elke "kolom" van een gegevensframe dezelfde lengte hebben. Als u probeert een data.frame te maken op basis van vectoren met verschillende lengten, resulteert dit in een fout. (Probeer data.frame(x = 1:3, y = 1:4)
te voeren om de resulterende fout te zien.)
Als testgevallen voor gegevensframes worden sommige gegevens standaard door R verstrekt. Een van hen is iris, als volgt geladen:
mydataframe <- iris
str(mydataframe)
Converteer gegevens die in een lijst zijn opgeslagen naar één gegevensframe met behulp van do.call
Als u uw gegevens in een lijst hebt opgeslagen en u wilt deze lijst naar een gegevensframe do.call
, is de functie do.call
een gemakkelijke manier om dit te bereiken. Het is echter belangrijk dat alle lijstelementen dezelfde lengte hebben om onbedoeld hergebruik van waarden te voorkomen.
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
Het werkt ook als uw lijst zelf uit dataframes bestaat.
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
Converteer alle kolommen van een data.frame naar tekenklasse
Een veel voorkomende taak is om alle kolommen van een data.frame te converteren naar tekenklasse voor eenvoudige manipulatie, zoals in het geval van het verzenden van data.frames naar een RDBMS of het samenvoegen van data.frames met factoren waarbij niveaus kunnen verschillen tussen invoergegevens.frames .
De beste tijd om dit te doen is wanneer de gegevens worden ingelezen - bijna alle invoermethoden waarmee gegevensframes worden gemaakt, hebben een optie stringsAsFactors
die kunnen worden ingesteld op FALSE
.
Als de gegevens al zijn gemaakt, kunnen factorkolommen worden geconverteerd naar tekenkolommen, zoals hieronder wordt weergegeven.
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)
})
Rijen op kolomwaarden instellen
Ingebouwde functies kunnen rows
onderverdelen met columns
die aan voorwaarden voldoen.
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))
Om rows
te vinden met 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
subset op basis van price_Elasticity > 0
en 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