Zoeken…


Basisgebruik van split

split maakt het mogelijk om een vector of een data.frame in emmers te verdelen met betrekking tot een factor / groepsvariabelen. Deze ventilatie in emmers neemt de vorm aan van een lijst, die vervolgens kan worden gebruikt om groepsgewijze berekening toe te passen ( for lussen of lapply / sapply ).

Eerste voorbeeld toont het gebruik van split op een vector:

Overweeg de volgende vector letters:

testdata <- c("e", "o", "r", "g", "a", "y", "w", "q", "i", "s", "b", "v", "x", "h", "u")

Doel is om die letters te scheiden in voyels en consonants , dat wil zeggen deze op te splitsen naar lettertype.

Laten we eerst een groeperingsvector maken:

 vowels <- c('a','e','i','o','u','y')
 letter_type <- ifelse(testdata %in% vowels, "vowels", "consonants") 

Merk op dat letter_type dezelfde lengte heeft die onze vector testdata . Nu kunnen we deze testgegevens split in de twee groepen, vowels en consonants :

split(testdata, letter_type)
#$consonants
#[1] "r" "g" "w" "q" "s" "b" "v" "x" "h"

#$vowels
#[1] "e" "o" "a" "y" "i" "u"

Het resultaat is dus een lijst met namen die afkomstig zijn van onze groepering vector / factor letter_type .

split heeft ook een methode om met data.frames om te gaan.

Overweeg bijvoorbeeld iris :

data(iris)

Door split , kan men een lijst maken met één data.frame per irisspecie (variabele: Species):

> liris <- split(iris, iris$Species)
> names(liris)
[1] "setosa"     "versicolor" "virginica"
> head(liris$setosa)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

(bevat alleen gegevens voor setosa-groep).

Een voorbeeld van een bewerking zou zijn om de correlatiematrix per irissoort te berekenen; men zou dan lapply :

> (lcor <- lapply(liris, FUN=function(df) cor(df[,1:4])))

    $setosa
             Sepal.Length Sepal.Width Petal.Length Petal.Width
Sepal.Length    1.0000000   0.7425467    0.2671758   0.2780984
Sepal.Width     0.7425467   1.0000000    0.1777000   0.2327520
Petal.Length    0.2671758   0.1777000    1.0000000   0.3316300
Petal.Width     0.2780984   0.2327520    0.3316300   1.0000000

$versicolor
             Sepal.Length Sepal.Width Petal.Length Petal.Width
Sepal.Length    1.0000000   0.5259107    0.7540490   0.5464611
Sepal.Width     0.5259107   1.0000000    0.5605221   0.6639987
Petal.Length    0.7540490   0.5605221    1.0000000   0.7866681
Petal.Width     0.5464611   0.6639987    0.7866681   1.0000000

$virginica
             Sepal.Length Sepal.Width Petal.Length Petal.Width
Sepal.Length    1.0000000   0.4572278    0.8642247   0.2811077
Sepal.Width     0.4572278   1.0000000    0.4010446   0.5377280
Petal.Length    0.8642247   0.4010446    1.0000000   0.3221082
Petal.Width     0.2811077   0.5377280    0.3221082   1.0000000

Dan kunnen we per groep het beste paar gecorreleerde variabelen ophalen: (correlatiematrix wordt hervormd / gesmolten, diagonaal wordt uitgefilterd en het selecteren van de beste record wordt uitgevoerd)

> library(reshape)
> (topcor <- lapply(lcor, FUN=function(cormat){
   correlations <- melt(cormat,variable_name="correlatio); 
   filtered <- correlations[correlations$X1 != correlations$X2,];
   filtered[which.max(filtered$correlation),]
}))    

$setosa
           X1           X2     correlation
2 Sepal.Width Sepal.Length       0.7425467

$versicolor
            X1           X2     correlation
12 Petal.Width Petal.Length       0.7866681

$virginica
            X1           X2     correlation
3 Petal.Length Sepal.Length       0.8642247

Merk op dat één berekeningen op een dergelijk groepsgewijs niveau worden uitgevoerd, dat men misschien geïnteresseerd is in het stapelen van de resultaten, wat kan worden gedaan met:

> (result <- do.call("rbind", topcor))

                     X1           X2     correlation
setosa      Sepal.Width Sepal.Length       0.7425467
versicolor  Petal.Width Petal.Length       0.7866681
virginica  Petal.Length Sepal.Length       0.8642247

Split gebruiken in het split-apply-combineren paradigma

Een populaire vorm van gegevensanalyse is split-apply-combineren , waarin u uw gegevens in groepen splitst, een soort verwerking op elke groep toepast en vervolgens de resultaten combineert.

Laten we een gegevensanalyse overwegen waarbij we de twee auto's met de beste mijl per gallon (mpg) voor elke cilindertelling (cyl) in de ingebouwde mtcars-gegevensset willen verkrijgen. Eerst splitsen we het mtcars gegevensframe op aantal cilinders:

(spl <- split(mtcars, mtcars$cyl))
# $`4`
#                 mpg cyl  disp  hp drat    wt  qsec vs am gear carb
# Datsun 710     22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
# Merc 240D      24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
# Merc 230       22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
# Fiat 128       32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
# ...
# 
# $`6`
#                 mpg cyl  disp  hp drat    wt  qsec vs am gear carb
# Mazda RX4      21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
# Mazda RX4 Wag  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
# Hornet 4 Drive 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
# Valiant        18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
# ...
# 
# $`8`
#                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
# Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
# Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
# Merc 450SE          16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
# Merc 450SL          17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
# ...

Dit heeft een lijst met gegevensframes geretourneerd, één voor elke cilindertelling. Zoals aangegeven door de uitvoer, kunnen we de relevante spl$`6` verkrijgen met spl$`4` , spl$`6` en spl$`8` (sommigen vinden het visueel aantrekkelijker om spl$"4" of spl[["4"]] plaats daarvan).

Nu kunnen we lapply om door deze lijst te bladeren en onze functie toe te passen die de auto's met de beste 2 mpg-waarden uit elk van de lapply extraheert:

(best2 <- lapply(spl, function(x) tail(x[order(x$mpg),], 2)))
# $`4`
#                 mpg cyl disp hp drat    wt  qsec vs am gear carb
# Fiat 128       32.4   4 78.7 66 4.08 2.200 19.47  1  1    4    1
# Toyota Corolla 33.9   4 71.1 65 4.22 1.835 19.90  1  1    4    1
# 
# $`6`
#                 mpg cyl disp  hp drat    wt  qsec vs am gear carb
# Mazda RX4 Wag  21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
# Hornet 4 Drive 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
# 
# $`8`
#                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
# Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
# Pontiac Firebird  19.2   8  400 175 3.08 3.845 17.05  0  0    3    2

Eindelijk kunnen we alles combineren met behulp van rbind . We willen rbind(best2[["4"]], best2[["6"]], best2[["8"]]) , maar dit zou vervelend zijn als we een enorme lijst hadden. Daarom gebruiken we:

do.call(rbind, best2)
#                      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
# 4.Fiat 128          32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
# 4.Toyota Corolla    33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
# 6.Mazda RX4 Wag     21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
# 6.Hornet 4 Drive    21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
# 8.Hornet Sportabout 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
# 8.Pontiac Firebird  19.2   8 400.0 175 3.08 3.845 17.05  0  0    3    2

Dit retourneert het resultaat van rbind (argument 1, een functie) waarbij alle elementen van best2 (argument 2, een lijst) zijn doorgegeven als argumenten.

Met eenvoudige analyses zoals deze kan het compacter (en mogelijk veel minder leesbaar!) Zijn om de hele split-apply-maaidorser in een enkele coderegel te doen:

do.call(rbind, lapply(split(mtcars, mtcars$cyl), function(x) tail(x[order(x$mpg),], 2)))

Het is ook vermeldenswaard dat de lapply(split(x,f), FUN) als alternatief kan worden ingelijst met de functie ?by lapply(split(x,f), FUN) :

by(mtcars, mtcars$cyl, function(x) tail(x[order(x$mpg),], 2))
do.call(rbind, by(mtcars, mtcars$cyl, function(x) tail(x[order(x$mpg),], 2)))


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow