Elegante Indizierung bis zum Ende des Vektors / der Matrix

73

Kann man in R sagen - ich möchte alle Indizes von der Position ibis zum Ende des Vektors / der Matrix? Angenommen, ich möchte eine Submatrix ab der 3. Spalte. Ich weiß derzeit nur so:

A = matrix(rep(1:8, each = 5), nrow = 5) # just generate some example matrix...

A[,3:ncol(A)] # get submatrix from 3rd column onwards

Aber muss ich wirklich schreiben ncol(A)? Gibt es keine elegante Möglichkeit, "ab der 3. Spalte" zu sagen? So etwas wie A[,3:]? (oder A[,3:...])?

TMS
quelle

Antworten:

101

Manchmal ist es einfacher, R zu sagen, was Sie nicht wollen. Mit anderen Worten, schließen Sie Spalten mithilfe der negativen Indizierung aus der Matrix aus:

Hier sind zwei alternative Möglichkeiten, mit denen beide die gleichen Ergebnisse erzielen:

A[, -(1:2)]
A[, -seq_len(2)]

Ergebnisse:

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    3    4    5    6    7    8
[2,]    3    4    5    6    7    8
[3,]    3    4    5    6    7    8
[4,]    3    4    5    6    7    8
[5,]    3    4    5    6    7    8

Um Ihre Frage wie gewünscht zu beantworten: Verwenden Sie ncoldiese Option , um die Anzahl der Spalten zu ermitteln. (Ebenso ist nrowdort die Anzahl der Zeilen zu ermitteln.)

A[, 3:ncol(A)]

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    3    4    5    6    7    8
[2,]    3    4    5    6    7    8
[3,]    3    4    5    6    7    8
[4,]    3    4    5    6    7    8
[5,]    3    4    5    6    7    8
Andrie
quelle
17

Für Zeilen (nicht Spalten gemäß Ihrem Beispiel) dann head()und tail()könnte verwendet werden.

A <- matrix(rep(1:8, each = 5), nrow = 5)
tail(A, 3)

ist fast das gleiche wie

A[3:dim(A)[1],]

(Die gedruckten Rownamen / Indizes sind unterschiedlich).

Diese funktionieren auch für Vektoren und Datenrahmen:

> tail(1:10, 4)
[1]  7  8  9 10
> tail(data.frame(A = 1:5, B = 1:5), 3)
  A B
3 3 3
4 4 4
5 5 5

Für die Spaltenversionen könnten Sie sich anpassen tail(), aber es ist etwas schwieriger. Ich frage mich, ob NROW()und NCOL()könnte hier nützlich sein, anstatt dim()?

> A[, 3:NCOL(A)]
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    3    4    5    6    7    8
[2,]    3    4    5    6    7    8
[3,]    3    4    5    6    7    8
[4,]    3    4    5    6    7    8
[5,]    3    4    5    6    7    8

Oder drehen Sie dies auf den Kopf und anstatt R nach Dingen zu fragen, bitten Sie es, stattdessen Dinge fallen zu lassen. Hier ist eine Funktion, die dies zusammenfasst:

give <- function(x, i, dimen = 1L) {
    ind <- seq_len(i-1)
    if(isTRUE(all.equal(dimen, 1L))) { ## rows
        out <- x[-ind, ]
    } else if(isTRUE(all.equal(dimen, 2L))) { ## cols
        out <- x[, -ind]
    } else {
        stop("Only for 2d objects")
    }
    out
}

> give(A, 3)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,]    1    2    3    4    5    6    7    8
[2,]    1    2    3    4    5    6    7    8
[3,]    1    2    3    4    5    6    7    8
> give(A, 3, dimen = 2)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    3    4    5    6    7    8
[2,]    3    4    5    6    7    8
[3,]    3    4    5    6    7    8
[4,]    3    4    5    6    7    8
[5,]    3    4    5    6    7    8
Gavin Simpson
quelle
1

Sie können die folgende Anweisung verwenden:

A[, 3:length(A[, 1])]
Reza Sadeghi
quelle
Wenn Sie viel Teilmenge machen wollen, erstellen Sie zuerst dima <- dim(A)und referenzieren Sie dann einfach, z. B. `A [, 3: dima [1]]`
Carl Witthoft