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 parentesdata data[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 $ för en data$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


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow