2016-11-03 7 views
2

Ich versuche, einen logischen Operator auf Spalten von data.table anzuwenden, was gut funktioniert ohne by = groups, aber mit by = groups passiert etwas Seltsames. Ich verwende R 3.3.1 und data.table 1.9.6 (aus CRAN).logische Operatoren in data.table mit by-groups

Hier ist ein Beispiel Datensatz:

library(data.table) 
# x <- matrix(rnorm(10),ncol=2) 
x <- structure(c(0.323618333400921, -0.103619160085676, -0.823322722581548, 
-0.0175726272468397, 2.17286179204364, 1.63465793636681, 0.258469984285221, 
-0.411622451584, 0.22594247704226, 0.114427086028551), .Dim = c(5L, 2L)) 

dt <- data.table(x) 
dt$id <- c(1,1,1,2,2) 
dt 

##    V1   V2 id 
## 1: 0.32361833 1.6346579 1 
## 2: -0.10361916 0.2584700 1 
## 3: -0.82332272 -0.4116225 1 
## 4: -0.01757263 0.2259425 2 
## 5: 2.17286179 0.1144271 2 

Lasst sie sagen, dass ich, wenn kumulativ Minimum möchte wissen (das heißt, in der aktuellen Zeile der Minimalwert in jeder Spalte entweder vom Beginn der Probe oder von der Anfang der Gruppe by = in die aktuelle Zeile) ist unter Null. Wenn es keine by = Gruppen gibt, sind wir gut:

dt[, cummin(.SD), .SDcols=1:2] 
##   V1   V2 
## 1: 0.3236183 1.6346579 
## 2: -0.1036192 0.2584700 
## 3: -0.8233227 -0.4116225 
## 4: -0.8233227 -0.4116225 
## 5: -0.8233227 -0.4116225 

> dt[, cummin(.SD)<0, .SDcols=1:2] 
##   V1 V2 
## [1,] FALSE FALSE 
## [2,] TRUE FALSE 
## [3,] TRUE TRUE 
## [4,] TRUE TRUE 
## [5,] TRUE TRUE 

So weit so gut. Ich kann auch tatsächliche kumulative Minima mit von = Gruppen berechnen:

dt[, cummin(.SD), by=id] 
## id   V1   V2 
## 1: 1 0.32361833 1.6346579 
## 2: 1 -0.10361916 0.2584700 
## 3: 1 -0.82332272 -0.4116225 
## 4: 2 -0.01757263 0.2259425 
## 5: 2 -0.01757263 0.1144271 

Allerdings, wenn ich versuche, nach wie vor die Indikatorvariablen zu berechnen, wird die Ausgabe wie folgt:

dt[, (cummin(.SD)<0), by=id] 
##  id V1 
## 1: 1 FALSE 
## 2: 1 TRUE 
## 3: 1 TRUE 
## 4: 1 FALSE 
## 5: 1 FALSE 
## 6: 1 TRUE 
## 7: 2 TRUE 
## 8: 2 TRUE 
## 9: 2 FALSE 
## 10: 2 FALSE 

Statt 2 Variablen 5 Obs. jeder hat einen mit 10. Es scheint, dass die Variablen innerhalb jeder By-Group übereinander gestapelt sind. Wie soll ich das richtig machen?

+0

Sie können diese Syntax, um zu versuchen. 'Dt [(cummin (V1) <0, cummin (V2) <0) durch = id] ' – HubertL

+0

Danke! Das funktioniert. Leider habe ich in der eigentlichen Anwendung ein paar tausend dieser Spalten, also bin ich mir nicht sicher, was wäre ein praktischer Weg, damit umzugehen ... – laxxy

+1

Meine Vermutung ist, dass 'cummin' eine' data.frame' Methode hat , also gerade ('cummin (dt)' funktioniert für Ihren ersten Versuch), während '(cummin (.SD) <0)' eine Matrix ist (die nur ein Vektor ist) und daher, während sie von Gruppe "Daten" geparst wird. Tisch "behandelt es anders. –

Antwort

3

Es wird mit lapply arbeiten:

dt[,lapply(.SD,function(x) cummin(x)<0),by="id"] 
    id V1 V2 
1: 1 FALSE FALSE 
2: 1 TRUE FALSE 
3: 1 TRUE TRUE 
4: 2 TRUE FALSE 
5: 2 TRUE FALSE 

Wie von David Arenburg kommentiert, so scheint es, dass es mit cummin(.SD) funktioniert, weil es ein Datum vorhanden ist. Rahmen und es funktioniert nicht mit cummin(.SD)<0, die eine Matrix ist. So eine andere Lösung ist es, die Matrix als data.frame würfen

dt[, (as.data.frame(cummin(.SD)<0)), by=id] 
    id V1 V2 
1: 1 FALSE FALSE 
2: 1 TRUE FALSE 
3: 1 TRUE TRUE 
4: 2 TRUE FALSE 
5: 2 TRUE FALSE 
+0

Danke! Das funktioniert. – laxxy

+1

Auch (ohne anonyme Funktionen) '' 'dt [, lapply (cummin (.SD),' <', 0), durch = id]' '' (obwohl 'lapply' auf' .SD' ist besser als nur 'cummin (.SD)' weil es Matrix-Konvertierungen vermeidet –

1

Sie können so etwas wie dies versuchen:

dt2 <- dt[, cummin(.SD), by = id] 
results <- data.table(dt2[, .SD<0]) 
results$id <- dt$id 

results 
    id V1 V2 
1: 1 FALSE FALSE 
2: 1 TRUE FALSE 
3: 1 TRUE TRUE 
4: 2 TRUE FALSE 
5: 2 TRUE FALSE 
Verwandte Themen