R Language
subsetting
Ricerca…
introduzione
Dato un oggetto R, possiamo richiedere un'analisi separata per una o più parti dei dati in essa contenuti. Il processo per ottenere queste parti dei dati da un dato oggetto è chiamato subsetting
.
Osservazioni
Valori mancanti:
Valori mancanti ( NA
) utilizzati in subsetting con [
return NA
da un indice NA
seleziona un elemento sconosciuto e quindi restituisce NA nell'elemento corrispondente ..
Il tipo "predefinito" di NA
è "logico" ( typeof(NA)
), il che significa che, come ogni vettore "logico" utilizzato in subsetting, verrà riciclato per corrispondere alla lunghezza dell'oggetto subsetted. Quindi x[NA]
è equivalente a x[as.logical(NA)]
che è equivalente a x[rep_len(as.logical(NA), length(x))]
e, di conseguenza, restituisce un valore mancante ( NA
) per ogni elemento di x
. Come esempio:
x <- 1:3
x[NA]
## [1] NA NA NA
Durante l'indicizzazione con "numerico" / "intero" NA
seleziona un singolo elemento NA
(per ogni NA
nell'indice):
x[as.integer(NA)]
## [1] NA
x[c(NA, 1, NA, NA)]
## [1] NA 1 NA NA
Compensazione fuori dai limiti:
L'operatore [
, con un argomento passato, consente indici che sono > length(x)
e restituisce NA
per vettori atomici o NULL
per vettori generici. Al contrario, con [[
e quando [
vengono passati più argomenti (ad es. Sottotitoli da oggetti con length(dim(x)) > 2
) viene restituito un errore:
(1:3)[10]
## [1] NA
(1:3)[[10]]
## Error in (1:3)[[10]] : subscript out of bounds
as.matrix(1:3)[10]
## [1] NA
as.matrix(1:3)[, 10]
## Error in as.matrix(1:3)[, 10] : subscript out of bounds
list(1, 2, 3)[10]
## [[1]]
## NULL
list(1, 2, 3)[[10]]
## Error in list(1, 2, 3)[[10]] : subscript out of bounds
Il comportamento è lo stesso quando si esegue il subsetting con i vettori "character", che non sono uguali anche nell'attributo "names" dell'oggetto:
c(a = 1, b = 2)["c"]
## <NA>
## NA
list(a = 1, b = 2)["c"]
## <NA>
## NULL
Argomenti di aiuto:
Vedi ?Extract
per ulteriori informazioni.
Vettori atomici
I vettori atomici (che esclude elenchi ed espressioni, che sono anche vettori) sono sottoinsieme usando [
operatore:
# create an example vector
v1 <- c("a", "b", "c", "d")
# select the third element
v1[3]
## [1] "c"
L'operatore [
può anche prendere un vettore come argomento. Ad esempio, per selezionare il primo e il terzo elemento:
v1 <- c("a", "b", "c", "d")
v1[c(1, 3)]
## [1] "a" "c"
Alcune volte potremmo richiedere di omettere un particolare valore dal vettore. Questo può essere ottenuto usando un segno negativo ( -
) prima dell'indice di quel valore. Ad esempio, per omettere di omettere il primo valore da v1, utilizzare v1[-1]
. Questo può essere esteso a più di un valore in modo diretto. Ad esempio, v1[-c(1,3)]
.
> v1[-1]
[1] "b" "c" "d"
> v1[-c(1,3)]
[1] "b" "d"
In alcune occasioni, vorremmo sapere, soprattutto, quando la lunghezza del vettore è grande, indice di un valore particolare, se esiste:
> v1=="c"
[1] FALSE FALSE TRUE FALSE
> which(v1=="c")
[1] 3
Se il vettore atomico ha nomi (un attributo names
), può essere sottoinsieme usando un vettore di caratteri di nomi:
v <- 1:3
names(v) <- c("one", "two", "three")
v
## one two three
## 1 2 3
v["two"]
## two
## 2
L'operatore [[
può anche essere utilizzato per indicizzare i vettori atomici, con differenze in quanto accetta un vettore di indicizzazione con una lunghezza di uno e elimina tutti i nomi presenti:
v[[c(1, 2)]]
## Error in v[[c(1, 2)]] :
## attempt to select more than one element in vectorIndex
v[["two"]]
## [1] 2
I vettori possono anche essere sottoinsieme utilizzando un vettore logico. Contrariamente al subsettorio con i vettori numerici e caratteri, il vettore logico utilizzato per il sottoinsieme deve essere uguale alla lunghezza del vettore i cui elementi vengono estratti, quindi se un vettore logico y
è usato per subset x
, cioè x[y]
, se length(y) < length(x)
allora y
sarà riciclato per abbinare la length(x)
:
v[c(TRUE, FALSE, TRUE)]
## one three
## 1 3
v[c(FALSE, TRUE)] # recycled to 'c(FALSE, TRUE, FALSE)'
## two
## 2
v[TRUE] # recycled to 'c(TRUE, TRUE, TRUE)'
## one two three
## 1 2 3
v[FALSE] # handy to discard elements but save the vector's type and basic structure
## named integer(0)
elenchi
Un elenco può essere sottoinsieme con [
:
l1 <- list(c(1, 2, 3), 'two' = c("a", "b", "c"), list(10, 20))
l1
## [[1]]
## [1] 1 2 3
##
## $two
## [1] "a" "b" "c"
##
## [[3]]
## [[3]][[1]]
## [1] 10
##
## [[3]][[2]]
## [1] 20
l1[1]
## [[1]]
## [1] 1 2 3
l1['two']
## $two
## [1] "a" "b" "c"
l1[[2]]
## [1] "a" "b" "c"
l1[['two']]
## [1] "a" "b" "c"
Nota che il risultato di l1[2]
è ancora un elenco, poiché [
operatore seleziona gli elementi di un elenco, restituendo un elenco più piccolo. L'operatore [[
operatore estrae gli elementi della lista, restituendo un oggetto del tipo dell'elemento della lista.
Gli elementi possono essere indicizzati per numero o una stringa di caratteri del nome (se esiste). Più elementi possono essere selezionati con [
passando un vettore di numeri o stringhe di nomi. Indicizzazione con un vettore di length > 1
in [
e [[
restituisce una "lista" con gli elementi specificati e un sottoinsieme ricorsivo (se disponibile), rispettivamente :
l1[c(3, 1)]
## [[1]]
## [[1]][[1]]
## [1] 10
##
## [[1]][[2]]
## [1] 20
##
##
## [[2]]
## [1] 1 2 3
Rispetto a:
l1[[c(3, 1)]]
## [1] 10
che è equivalente a:
l1[[3]][[1]]
## [1] 10
L'operatore $
ti consente di selezionare gli elementi della lista esclusivamente per nome, ma a differenza di [
e [[
, non richiede virgolette. Come operatore infisso, $
può solo prendere un solo nome:
l1$two
## [1] "a" "b" "c"
Inoltre, l'operatore $
consente la corrispondenza parziale per impostazione predefinita:
l1$t
## [1] "a" "b" "c"
in contrasto con [[
dove è necessario specificare se è ammessa la corrispondenza parziale:
l1[["t"]]
## NULL
l1[["t", exact = FALSE]]
## [1] "a" "b" "c"
options(warnPartialMatchDollar = TRUE)
impostazione options(warnPartialMatchDollar = TRUE)
, viene dato un "avvertimento" quando la corrispondenza parziale avviene con $
:
l1$t
## [1] "a" "b" "c"
## Warning message:
## In l1$t : partial match of 't' to 'two'
matrici
Per ogni dimensione di un oggetto, l'operatore [
accetta un argomento. I vettori hanno una dimensione e accettano un argomento. Le matrici e i frame di dati hanno due dimensioni e prendono due argomenti, dati come [i, j]
dove i
è la riga e j
è la colonna. L'indicizzazione inizia da 1.
## a sample matrix
mat <- matrix(1:6, nrow = 2, dimnames = list(c("row1", "row2"), c("col1", "col2", "col3")))
mat
# col1 col2 col3
# row1 1 3 5
# row2 2 4 6
mat[i,j]
è l'elemento nella i
-th row, j
-th column del mat
. Ad esempio, un valore i
di 2
e un valore j
di 1
indicano il numero nella seconda riga e la prima colonna della matrice. L'omissione di i
o j
restituisce tutti i valori in quella dimensione.
mat[ , 3]
## row1 row2
## 5 6
mat[1, ]
# col1 col2 col3
# 1 3 5
Quando la matrice ha nomi di righe o colonne (non richiesti), questi possono essere utilizzati per il subset:
mat[ , 'col1']
# row1 row2
# 1 2
Per impostazione predefinita, il risultato di un sottoinsieme sarà semplificato se possibile. Se il sottoinsieme ha solo una dimensione, come negli esempi precedenti, il risultato sarà un vettore unidimensionale piuttosto che una matrice bidimensionale. Questo valore predefinito può essere ignorato con l'argomento drop = FALSE
su [
:
## This selects the first row as a vector
class(mat[1, ])
# [1] "integer"
## Whereas this selects the first row as a 1x3 matrix:
class(mat[1, , drop = F])
# [1] "matrix"
Ovviamente, le dimensioni non possono essere eliminate se la selezione stessa ha due dimensioni:
mat[1:2, 2:3] ## A 2x2 matrix
# col2 col3
# row1 3 5
# row2 4 6
Selezione delle singole voci della matrice in base alle loro posizioni
È anche possibile utilizzare una matrice Nx2 per selezionare N singoli elementi da una matrice (come il funzionamento di un sistema di coordinate). Se si desidera estrarre, in un vettore, le voci di una matrice nella (1st row, 1st column), (1st row, 3rd column), (2nd row, 3rd column), (2nd row, 1st column)
questo può si può fare facilmente creando una matrice di indici con quelle coordinate e usando quella per suddividere la matrice:
mat
# col1 col2 col3
# row1 1 3 5
# row2 2 4 6
ind = rbind(c(1, 1), c(1, 3), c(2, 3), c(2, 1))
ind
# [,1] [,2]
# [1,] 1 1
# [2,] 1 3
# [3,] 2 3
# [4,] 2 1
mat[ind]
# [1] 1 5 6 2
Nell'esempio sopra, la prima colonna della ind
matrice si riferisce a righe mat
, 2a colonna di ind
riferisce alle colonne in mat
.
Cornici di dati
La suddivisione di un frame di dati in un frame di dati più piccolo può essere eseguita allo stesso modo del subset di un elenco.
> df3 <- data.frame(x = 1:3, y = c("a", "b", "c"), stringsAsFactors = FALSE)
> df3
## x y
## 1 1 a
## 2 2 b
## 3 3 c
> df3[1] # Subset a variable by number
## x
## 1 1
## 2 2
## 3 3
> df3["x"] # Subset a variable by name
## x
## 1 1
## 2 2
## 3 3
> is.data.frame(df3[1])
## TRUE
> is.list(df3[1])
## TRUE
La suddivisione di un dataframe in un vettore di colonna può essere eseguita utilizzando doppie parentesi [[]] o l'operatore del simbolo di dollaro $.
> df3[[2]] # Subset a variable by number using [[ ]]
## [1] "a" "b" "c"
> df3[["y"]] # Subset a variable by name using [[ ]]
## [1] "a" "b" "c"
> df3$x # Subset a variable by name using $
## [1] 1 2 3
> typeof(df3$x)
## "integer"
> is.vector(df3$x)
## TRUE
La suddivisione di un dato come matrice bidimensionale può essere eseguita utilizzando i
termini i
e j
.
> df3[1, 2] # Subset row and column by number
## [1] "a"
> df3[1, "y"] # Subset row by number and column by name
## [1] "a"
> df3[2, ] # Subset entire row by number
## x y
## 2 2 b
> df3[ , 1] # Subset all first variables
## [1] 1 2 3
> df3[ , 1, drop = FALSE]
## x
## 1 1
## 2 2
## 3 3
Nota: la subfornitura di j
(colonna) da sola semplifica il tipo della variabile, ma l'inserimento di solo i
restituisce un data.frame
, poiché le diverse variabili possono avere tipi e classi diversi. L'impostazione del parametro drop
su FALSE
mantiene il frame dei dati.
> is.vector(df3[, 2])
## TRUE
> is.data.frame(df3[2, ])
## TRUE
> is.data.frame(df3[, 2, drop = FALSE])
## TRUE
Altri oggetti
[
E [[
operatori sono funzioni primitive che sono generiche. Ciò significa che qualsiasi oggetto in R (in particolare isTRUE(is.object(x))
--ie ha un attributo "class" esplicito) può avere il proprio comportamento specificato al momento del subsetting; cioè ha i suoi metodi per [
e / o [[
.
Ad esempio, questo è il caso degli oggetti "data.frame" ( is.object(iris)
) in cui i [.data.frame
e [[.data.frame
sono definiti e sono fatti per mostrare entrambi i caratteri "matrix" e sottotitolo "elenco". Con la forzatura di un errore quando si sostituisce un "data.frame", vediamo che, in realtà, una funzione [.data.frame
stata chiamata quando abbiamo usato -just [
.
iris[invalidArgument, ]
## Error in `[.data.frame`(iris, invalidArgument, ) :
## object 'invalidArgument' not found
Senza ulteriori dettagli sull'argomento attuale, un esempio [
metodo:
x = structure(1:5, class = "myClass")
x[c(3, 2, 4)]
## [1] 3 2 4
'[.myClass' = function(x, i) cat(sprintf("We'd expect '%s[%s]' to be returned but this a custom `[` method and should have a `?[.myClass` help page for its behaviour\n", deparse(substitute(x)), deparse(substitute(i))))
x[c(3, 2, 4)]
## We'd expect 'x[c(3, 2, 4)]' to be returned but this a custom `[` method and should have a `?[.myClass` help page for its behaviour
## NULL
Possiamo superare l'invio del metodo di [
usando l'equivalente non generico .subset
(e .subset2
per [[
). Questo è particolarmente utile ed efficiente quando si programmano le nostre "classi" e si vuole evitare di aggirare il unclass(x)
come unclass(x)
) quando si calcolano in modo efficiente le nostre "classi" (evitando il metodo di invio e copia di oggetti):
.subset(x, c(3, 2, 4))
## [1] 3 2 4
Indicizzazione vettoriale
Per questo esempio, useremo il vettore:
> x <- 11:20
> x
[1] 11 12 13 14 15 16 17 18 19 20
I vettori R sono a 1 indice, quindi x[1]
restituirà 11
. Possiamo anche estrarre un sotto-vettore di x
passando un vettore di indici all'operatore di parentesi:
> x[c(2,4,6)]
[1] 12 14 16
Se passiamo un vettore di indici negativi, R restituirà un sotto-vettore con gli indici specificati esclusi:
> x[c(-1,-3)]
[1] 12 14 15 16 17 18 19 20
Possiamo anche passare un vettore booleano all'operatore della parentesi, nel qual caso restituisce un sub-vettore corrispondente alle coordinate in cui il vettore di indicizzazione è TRUE
:
> x[c(rep(TRUE,5),rep(FALSE,5))]
[1] 11 12 13 14 15 16
Se il vettore di indicizzazione è più breve della lunghezza dell'array, verrà ripetuto, come in:
> x[c(TRUE,FALSE)]
[1] 11 13 15 17 19
> x[c(TRUE,FALSE,FALSE)]
[1] 11 14 17 20
Operazioni con la matrice elementare
Sia A e B due matrici della stessa dimensione. Gli operatori +
, -
, /
, *
, ^
quando usati con matrici della stessa dimensione eseguono le operazioni richieste sugli elementi corrispondenti delle matrici e restituiscono una nuova matrice della stessa dimensione. Queste operazioni sono solitamente definite operazioni basate sull'elemento.
Operatore | A op B | Senso |
---|---|---|
+ | A + B | Aggiunta di elementi corrispondenti di A e B |
- | A - B | Sottrae gli elementi di B dagli elementi corrispondenti di A |
/ | A / B | Divide gli elementi di A dagli elementi corrispondenti di B |
* | A * B | Moltiplica gli elementi di A dagli elementi corrispondenti di B |
^ | A ^ (- 1) | Ad esempio, fornisce una matrice i cui elementi sono reciproci di A |
Per la "vera" moltiplicazione della matrice, come si vede in Algebra lineare , usa %*%
. Ad esempio, la moltiplicazione di A con B è: A %*% B
I requisiti dimensionali sono che il ncol()
di A
sia lo stesso di nrow()
di B
Alcune funzioni utilizzate con le matrici
Funzione | Esempio | Scopo |
---|---|---|
nrow () | nrow (A) | determina il numero di righe di A |
ncol () | ncol (A) | determina il numero di colonne di A |
rownames () | rownames (A) | stampa i nomi delle righe della matrice A |
colnames () | colnames (A) | stampa i nomi delle colonne della matrice A |
rowMeans () | rowMeans (A) | calcola i mezzi di ciascuna riga della matrice A |
colMeans () | colMeans (A) | calcola i mezzi di ciascuna colonna della matrice A |
upper.tri () | upper.tri (A) | restituisce un vettore i cui elementi sono la parte superiore |
matrice triangolare di matrice quadrata A | ||
lower.tri () | lower.tri (A) | restituisce un vettore i cui elementi sono i più bassi |
matrice triangolare di matrice quadrata A | ||
det () | det (A) | risultati nel determinante della matrice A |
risolvere() | solve (A) | risulta nell'inverso della matrice non singolare A |
diag () | diag (A) | restituisce una matrice diagonale i cui elementi di diagnostica esterna sono zeri e |
le diagonali sono le stesse della matrice quadrata A | ||
t () | t (A) | restituisce la trasposizione della matrice A |
Eigen () | eigen (A) | ritarda gli autovalori e gli autovettori della matrice A |
is.matrix () | is.matrix (A) | restituisce VERO o FALSO a seconda che A sia una matrice o meno. |
as.matrix () | as.matrix (x) | crea una matrice fuori dal vettore x |