2016-09-30 3 views
3

Wenn ich diese einfache data.table verwenden (eine Spalte)eine data.table über Spaltennummern zugreifen und grep

mydata <- data.table(A=c("ID123", "ID22", "AAA", NA)) 

ich die Position der Zeilen beginnend mit „ID“ finden

grep("^ID", mydata[,A]) 

Wie bekomme ich das gleiche Ergebnis mit Zahlen statt? (Ich sage die erste Spalte).

Ich habe

versucht
grep("^ID", mydata[,1, with=F]) 

, aber es funktioniert nicht.

Und noch wichtiger, ich würde es in der data.table Weise tun, den Befehl innerhalb der Klammern einführend.

mydata[,grep("^ID",.SD), .SDcols=1] 

Aber das funktioniert nicht.

Ich habe diese Art und Weise gefunden, aber es ist zu verworren

mydata[,lapply(.SD, grep,pattern="ID"), .SDcols=1] 

Was ist der richtige Weg, es zu tun?

Ein bisschen komplexer:
Was, wenn ich gleichzeitig zählen möchte, wie viele Zeilen nicht NA sind und mit "ID" beginnen?

So etwas wie

any(!(grepl("^ID", mydata[,A]) | is.na(mydata[,A]))) 

aber kompakte und in den Klammern.

Ich mag nicht die Tatsache, dass Grep die NA als nicht übereinstimmend ansieht, anstatt auch eine NA auszugeben.

+0

Ich habe diesen Weg gefunden, aber es ist zu verworren mydata [, lapply (.SD, grep, pattern = " ID "), .SDcols = 1] – skan

+4

Die erste Antwort in den FAQ erklärt, warum es" in der Regel schlecht ist, auf Spalten nach Nummer und nicht nach Namen zu verweisen "https://rawgit.com/wiki/Rdatatable/data.table/ vignettes/datatable-faq.html # j-num Eine Möglichkeit, Zeilen zu zählen, ist 'mydata [A% like%"^ID "| is.na (A), .N] '-'% like% 'ist nur eine bequeme Abkürzung für' grepl'. Übrigens könnte Ihr Beispiel besser sein, wenn es eine NA enthält. – Frank

+0

Ich habe den Titel der Frage so geändert, dass die Anfrage genauer zusammengefasst wird. –

Antwort

2

One data.table Weg, um eine Spalte nach der Anzahl der Indexierung auf einen Spaltennamen zu konvertieren wäre, zu einem R-Symbol konvertieren und bewerten:

mydata[ , eval(as.symbol(names(mydata)[1]))] 
[1] "ID123" "ID22" "AAA" 

> grep("^ID", mydata[,eval(as.symbol(names(mydata)[1]))]) 
[1] 1 2 

Aber das ist nicht wirklich ein anerkannter Weg zum Erfolg wegen der DT FAQ # 1 sowie der Tatsache, dass Zeilennummern nicht als gültige Ziele betrachtet werden. Die Philosophie (wie ich es verstehe) ist, dass Zeilennummern zufällig sind und Sie sollten Ihre Datensätze mit eindeutigen Kennungen speichern.

+1

Wie wäre es mit 'mydata [[1]]'? –

+1

Hah. Vom Meister. Aber bevor ich den Autor dieses Kommentars sah, war ich bereit zu sagen, dass "[[" eine Listen-basierte Methode und keine True-Data.Table-Methode war. Aber ich könnte mich deswegen irren. Ich habe überprüft: '? '[[. Data.table' Keine Dokumentation für '[.data.table' in angegebenen Paketen und Bibliotheken: Sie könnten versuchen '?? [. Data.table' ' –

+0

Es gibt keine spezielle Methode für '[' '' '' '' '' '' data.table' 'also gibt es keinen Mechanismus oder eine Notwendigkeit zu dokumentieren. Nichts anderes und das ist beabsichtigt: es ist nur eine "Liste". Bitte benutzen Sie '[' 'und' $ 'in diesen Situationen. Ich mache. Es gibt ein Beispiel und einen Kommentar in 'example (data.table)': "DT [[" v "]] # wie DT [, v] aber viel schneller'" –

9

Vergessen Sie nicht, dass data.table auch eine list ist. Also, wenn Sie wirklich und nur eine ganze Spalte als ein Vektor wollen, dann ist es ermutigt, nur Basis-R-Methoden darauf zu verwenden: [[ und $.

mydata <- data.table(A=c("ID123", "ID22", "AAA")) 
mydata 
#  A 
#1: ID123 
#2: ID22 
#3: AAA 
grep("^ID", mydata[[1]]) # using a column number 
#[1] 1 2 
grep("^ID", mydata$A) 
#[1] 1 2 

Wenn Sie dies in einer Schleife müssen dann [[ und $ sind schneller, da sie den Aufwand für das Argument Prüfung innerhalb DT[...] vermeiden. Wenn es nur einen Anruf gibt, ist dieser Overhead vernachlässigbar.

grep("^ID", mydata[,1, with=F]) "funktioniert nicht" (bitte fügen Sie die Fehlermeldung, dass Sie statt "funktioniert nicht!"), Weil grep will einen Vektor, aber DT[] gibt immer eine Daten zurück.Tabelle, auch wenn 1-Spalte, für wichtige Typ Konsistenz, z. beim Verketten. mydata[[1]] direkt ist sauberer, aber eine andere Möglichkeit, nur zu veranschaulichen ist grep("^ID", mydata[,1,with=F][[1]]).

Wie Frank in den Kommentaren sagte, wird die Verwendung von Spaltennummern dringend von der Möglichkeit von Fehlern abgeraten, da sich Ihre Daten im Laufe der Monate und Jahre in die Zukunft ändern, wie die Dokumentation erklärt. Verwenden Sie stattdessen Spaltennamen innerhalb von DT[...].

Aber wenn Sie wirklich müssen, und manchmal gültig es ist, dann, wie etwa:

..theCol = DT[[theNumber]] 
DT[ grep(,..theCol) & ..theCol | ..theCol etc , ... ] 

Der .. Präfix in Ihren Variablennamen Art heißt „eine up“ wie ein Verzeichnispfad. Aber jeder Variablenname, der sicher kein Spaltenname ist, würde ausreichen. Auf diese Weise können Sie es mehrmals innerhalb von DT[...] verwenden, ohne den Tabellennamen DT und die Spaltennummer zu wiederholen, nur um die Spalte mehrmals per Nummer zu erreichen. (Wir versuchen, die Wiederholung des Symbolnamens so weit wie möglich zu vermeiden, um das Fehlerpotenzial aufgrund von Tippfehlern zu reduzieren.)

+0

Ich weiß, dass die Verwendung von Spaltennummern gefährlich sein kann, weil sie sich rechtzeitig ändern können. Aber manchmal müssen Sie sie verwenden, um auf viele Spalten gleichzeitig zu verweisen, oder weil diese Zahlen von einer vorherigen Filterung stammen. Meine Frage ist ein einfaches Beispiel, aber ich arbeite mit einer großen Tabelle mit 1700 Variablen. – skan

+0

Bitte, können Sie etwas mehr die Bedeutung von .. erklären? – skan

+0

Ich habe versucht ..theCol = DT [[1]] DT [, grep ("^ ID", .. theCol) | ! is.na (.. theCol)] aber das Ergebnis ist logisch (0) – skan

Verwandte Themen