R Language
Dataramar
Sök…
Syntax
data.frame (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, stringsAsFactors = default.stringsAsFactors ())
as.data.frame (x, row.names = NULL, valfri = FALSE, ...) # generisk funktion
as.data.frame (x, ..., stringsAsFactors = default.stringsAsFactors ()) # S3-metod för klass 'karaktär'
as.data.frame (x, row.names = NULL, valfria = FALSE, ..., stringsAsFactors = default.stringsAsFactors ()) # S3-metod för klass 'matrix'
is.data.frame (x)
Skapa en tom data.frame
En data.frame är en speciell typ av lista: den är rektangulär . Varje element (kolumn) i listan har samma längd och där varje rad har ett "radnamn". Varje kolumn har sin egen klass, men klassen för en kolumn kan skilja sig från klassen i en annan kolumn (till skillnad från en matris, där alla element måste ha samma klass).
I princip kan ett data.frame inte ha några rader och inga kolumner:
> structure(list(character()), class = "data.frame")
NULL
<0 rows> (or 0-length row.names)
Men detta är ovanligt. Det är vanligare att en data.frame har många kolumner och många rader. Här är en data.frame med tre rader och två kolumner ( a
är numerisk klass och b
är teckenklass):
> structure(list(a = 1:3, b = letters[1:3]), class = "data.frame")
[1] a b
<0 rows> (or 0-length row.names)
För att data.frame ska kunna skrivas ut måste vi ange några radnamn. Här använder vi bara siffrorna 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 blir det uppenbart att vi har en data.frame med 3 rader och 2 kolumner. Du kan kontrollera detta med nrow()
, ncol()
och 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 tillhandahåller två andra funktioner (förutom structure()
) som kan användas för att skapa en data.frame. Den första kallas intuitivt data.frame()
. Det kontrollerar att kolumnnamnen som du angav är giltiga, att listelementen är lika långa och ger några automatiskt genererade radnamn. Detta betyder att data.frame()
från data.frame()
nu kan vara exakt vad du förväntar dig:
> 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
Den andra funktionen kallas as.data.frame()
. Detta kan användas för att tvinga ett objekt som inte är ett data.frame till att vara ett data.frame genom att köra det genom data.frame()
. Tänk som exempel på en matris:
> m <- matrix(letters[1:9], nrow = 3)
> m
[,1] [,2] [,3]
[1,] "a" "d" "g"
[2,] "b" "e" "h"
[3,] "c" "f" "i"
Och resultatet:
> 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
Sätta in rader och kolumner från en dataram
Syntax för åtkomst till rader och kolumner: [
, [[
och $
Detta ämne täcker den vanligaste syntaxen för att få åtkomst till specifika rader och kolumner i en dataram. Dessa är
- Som en
matrix
med enstaka parentesdatadata[rows, columns]
- Använd rad- och kolumnnummer
- Använd kolumn (och rad) namn
- Gilla en
list
:- Med enstaka parenteser
data[columns]
att få en dataram - Med dubbla parenteser
data[[one_column]]
att få en vektor
- Med enstaka parenteser
- Med
$
för endata$column_name
Vi kommer att använda den inbyggda mtcars
dataramen för att illustrera.
Som en matris: data[rows, columns]
Med numeriska index
Med hjälp av den inbyggda mtcars
kan vi extrahera rader och kolumner med hjälp av []
parentes med komma med. Index före komma är rader:
# get the first row
mtcars[1, ]
# get the first five rows
mtcars[1:5, ]
På liknande sätt kolumner efter kommatecken:
# get the first column
mtcars[, 1]
# get the first, third and fifth columns:
mtcars[, c(1, 3, 5)]
Som visas ovan, om antingen rader eller kolumner lämnas tomma, kommer alla att väljas. mtcars[1, ]
anger den första raden med alla kolumner.
Med kolumn (och rad) namn
Hittills är detta identiskt med hur rader och kolumner med matriser nås. Med data.frame
s är det för det mesta att föredra att använda ett kolumnnamn till ett kolumnindex. Detta görs genom att använda ett character
med kolumnnamnet istället för numeric
med ett kolumnnummer:
# get the mpg column
mtcars[, "mpg"]
# get the mpg, cyl, and disp columns
mtcars[, c("mpg", "cyl", "disp")]
Även om mindre vanliga, kan radnamn också användas:
mtcars["Mazda Rx4", ]
Rader och kolumner tillsammans
Rad- och kolumnargumenten kan användas tillsammans:
# 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")]
En varning om dimensioner:
När du använder dessa metoder, om du extraherar flera kolumner, får du en dataram tillbaka. Men om du extraherar en enda kolumn får du en vektor, inte en dataram under standardalternativen.
## multiple columns returns a data frame
class(mtcars[, c("mpg", "cyl")])
# [1] "data.frame"
## single column returns a vector
class(mtcars[, "mpg"])
# [1] "numeric"
Det finns två sätt runt detta. Den ena är att behandla dataramen som en lista (se nedan), den andra är att lägga till ett drop = FALSE
argument. Detta säger R att inte "släppa oanvända dimensioner":
class(mtcars[, "mpg", drop = FALSE])
# [1] "data.frame"
Observera att matriser fungerar på samma sätt - som standard är en enda kolumn eller rad en vektor, men om du anger drop = FALSE
du behålla den som en kolumn eller matris på en rad.
Som en lista
Dataramar är i huvudsak list
, dvs. de är en lista över kolumnvektorer (som alla måste ha samma längd). Listor kan delas med hjälp av enstaka parenteser [
för en underlista eller dubbla parenteser [[
för ett enda element.
Med enstaka parentesdata data[columns]
När du använder enstaka parenteser och inga komma får du tillbaka kolumnen eftersom dataramar är kolumlistor.
mtcars["mpg"]
mtcars[c("mpg", "cyl", "disp")]
my_columns <- c("mpg", "cyl", "hp")
mtcars[my_columns]
Enkla parenteser som en lista kontra enkla parenteser som en matris Skillnaden mellan data[columns]
och data[, columns]
är att när man behandlar data.frame
som en list
(inget komma i parenteserna) kommer det returnerade objektet att vara ett data.frame
. Om du använder ett kommatecken för att behandla data.frame
som en matrix
kommer du att välja en enda kolumn för att välja en vektor men att välja flera kolumner kommer att returnera en 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"
Med data[[one_column]]
med dubbel parentes data[[one_column]]
För att extrahera en enda kolumn som en vektor när du behandlar din data.frame
som en list
kan du använda dubbla parenteser [[
. Detta fungerar bara för en enda kolumn åt gången.
# 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"]
Använd $
att komma åt kolumner
En enda kolumn kan extraheras med den magiska genvägen $
utan att använda ett citerat kolumnnamn:
# get the column "mpg"
mtcars$mpg
Kolumner som nås av $
kommer alltid att vara vektorer, inte dataramar.
Nackdelar med $
för åtkomst till kolumner
$
Kan vara en bekväm genväg, särskilt om du arbetar i en miljö (som RStudio) som automatiskt kommer att fylla i kolumnnamnet i detta fall. Dock har $
nackdelar också: det använder icke-standard utvärdering för att undvika behov av offert, vilket innebär att det inte fungerar om ditt kolumnnamn är lagrat i en variabel.
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
På grund av dessa problem används $
bäst i interaktiva R-sessioner när dina kolumnnamn är konstant. För programmatisk användning, till exempel för att skriva en generaliserbar funktion som kommer att användas på olika datamängder med olika kolumnnamn, bör $
undvikas.
Observera också att standardbeteendet är att använda partiell matchning endast när man extraherar från rekursiva objekt (utom miljöer) med $
# 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
Avancerad indexering: negativa och logiska index
När vi har möjlighet att använda siffror för ett index kan vi också använda negativa siffror för att utelämna vissa index eller en boolesk (logisk) vektor för att ange exakt vilka objekt som ska behållas.
Negativa index utelämnar element
mtcars[1, ] # first row
mtcars[ -1, ] # everything but the first row
mtcars[-(1:10), ] # everything except the first 10 rows
Logiska vektorer anger specifika element att behålla
Vi kan använda ett villkor som <
att generera en logisk vektor och bara extrahera raderna som uppfyller villkoret:
# 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, ]
Vi kan också kringgå steget att spara mellanvariabeln
# 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")]
Convenience-funktioner för att manipulera data.frames
Vissa bekvämlighetsfunktioner för att manipulera data.frames
är subset()
, transform()
, with()
och within()
.
delmängd
Funktionen subset()
låter dig data.frame
en data.frame
på ett mer bekvämt sätt (delmängden fungerar också med andra klasser):
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
I koden ovan ber vi bara om raderna i vilka cyl == 6
och för kolumnerna mpg
och hp
. Du kan uppnå samma resultat med []
med följande kod:
mtcars[mtcars$cyl == 6, c("mpg", "hp")]
omvandla
Funktionen transform()
är en bekvämhetsfunktion för att ändra kolumner i en data.frame
. Till exempel lägger följande kod till en annan kolumn med namnet mpg2
med resultatet av mpg^2
till mtcars
data.frame
:
mtcars <- transform(mtcars, mpg2 = mpg^2)
med och inom
Både with()
och within()
du utvärdera uttryck i data.frame
miljön, vilket möjliggör en något renare syntax, vilket sparar användningen av vissa $
eller []
.
Om du till exempel vill skapa, ändra och / eller ta bort flera kolumner i 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
})
Introduktion
Dataramar är troligen den datastruktur som du använder mest i dina analyser. En dataram är en speciell typ av lista som lagrar vektorer av samma längd i olika klasser. Du skapar dataramar med funktionen data.frame
. Exemplet nedan visar detta genom att kombinera en numerisk och en teckenvektor i en dataram. Den använder :
operatör, som kommer att skapa en vektor som innehåller alla heltal 1-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"
Dataramobjekt skrivs inte ut med citattecken, så kolumnens klass är inte alltid uppenbar.
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
Utan ytterligare undersökning kan inte "x" -kolumnerna i df1
och df2
differentieras. str
funktionen kan användas för att beskriva objekt mer detaljerat än klass.
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
Här ser du att df1
är ett data.frame
och har 3 observationer av 2 variabler, "x" och "y." Då får du höra att "x" har datatypen heltal (inte viktigt för den här klassen, men för våra ändamål uppträder det som en siffra) och "y" är en faktor med tre nivåer (en annan dataklass vi inte diskuterar). Det är viktigt att notera att dataramar som standard tvingar tecken till faktorer. Standardbeteendet kan ändras med stringsAsFactors
parametern:
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 är "kolumnen" ett tecken. Som nämnts ovan måste varje "kolumn" i en dataram ha samma längd. Att försöka skapa en data.frame från vektorer med olika längder resulterar i ett fel. (Prova att köra data.frame(x = 1:3, y = 1:4)
att se det resulterande felet.)
Som testfall för dataramar tillhandahålls vissa data av R som standard. En av dem är iris, laddad enligt följande:
mydataframe <- iris
str(mydataframe)
Konvertera data lagrade i en lista till en enda dataram med do.call
Om du har dina data lagrade i en lista och vill konvertera listan till en dataram är do.call
funktionen ett enkelt sätt att uppnå detta. Det är dock viktigt att alla listelement har samma längd för att förhindra oavsiktlig återvinning av värden.
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
Det fungerar också om listan består av själva dataramar.
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
Konvertera alla kolumner i en data.frame till teckenklass
En vanlig uppgift är att konvertera alla kolumner i en data.frame till karaktärsklass för att underlätta hantering, till exempel i fallet med att skicka data.frames till en RDBMS eller slå samman data.frames som innehåller faktorer där nivåer kan skilja sig mellan input data.frames .
Den bästa tiden att göra detta är när data läses in - nästan alla inmatningsmetoder som skapar dataramar har ett options stringsAsFactors
som kan ställas in på FALSE
.
Om informationen redan har skapats kan faktorkolumner konverteras till teckenkolumner som visas nedan.
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)
})
Ange rader efter kolumnvärden
Inbyggda funktioner kan dela rows
med columns
som uppfyller villkoren.
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))
price_Elasticity > 0
rows
med 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
delmängd baserat på price_Elasticity > 0
och 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