2016-05-12 16 views
-1

Ich versuche zu verstehen, wie man data.tables benutzt. Es läuft nicht gut.Wie unterteile ich eine data.table basierend auf einer anderen data.table?

Ich habe eine große data.table mit einer Reihe von Renditen und AUM. Ich unterteilte diese data.table in zwei data.tables, eine mit Returns und eine mit AUM. Ich möchte nun die returns data.table unterteilen, um nur die Renditen von Fonds mit AUM kleiner als das 50. Perzentil zu erhalten.

Ihnen eine Vorstellung zu geben, das ist mein Code:

fundDetails <- data.table(read.table("Fund_Deets.csv", sep = ",", fill = TRUE, quote="\"", header=TRUE)) 
fundNAV <- data.table(read.table("NAV_AUM.csv", sep = ",", fill = TRUE, quote="\"", header=TRUE)) 

allFundDetails <- fundDetails[Currency == 'USD'] 
allFundNAV <- fundNAV[Fund.ID %in% allFundDetails$Fund.ID] 
allFundAUM <- allFundNAV[Type == 'AUM', -c(1,3), with = FALSE] 
allFundAUM <- setnames(data.table(t(sapply(allFundAUM[,-1, with = FALSE],as.numeric))), as.character(allFundAUM$Fund.ID)) 
allFundReturns <- allFundNAV[Type == 'Return', -c(1,3), with = FALSE] 
allFundReturns <- setnames(data.table(t(sapply(allFundReturns[,-1, with = FALSE],as.numeric)/100)), as.character(allFundReturns$Fund.ID)) 
smallFundReturns <- data.table(sapply(allFundReturns, function(x) rep(NA, length(x)))) 

Daraus ergeben sich die folgenden drei Tabellen (smallFundReturns ist offensichtlich nur NA):

> allFundAUM[,1:10, with = FALSE] 
    33992 33261 38102 33264 33275 5606 41695 40483 41526 45993 
    1: NA NA NA NA NA NA NA NA  1 27 
    2: NA NA NA NA NA NA 117 NA  1 27 
    3: NA NA NA NA NA NA 120 NA  1 27 
    4: NA NA NA NA NA NA 133 NA  1 27 
    5: NA NA NA NA NA NA 146 NA  1 29 
---               
260: NA NA NA NA NA NA NA NA NA NA 
261: NA NA NA NA NA NA NA NA NA NA 
262: NA NA NA NA NA NA NA NA NA NA 
263: NA NA NA NA NA NA NA NA NA NA 
264: NA NA NA NA NA NA NA NA NA NA 
> allFundReturns[,1:10, with = FALSE] 
    33992 33261 38102 33264 33275 5606 41695 40483 41526 45993 
    1: NA NA NA NA NA NA  NA NA 0.0188 -0.0116 
    2: NA NA NA NA NA NA -0.0315 NA -0.0120 0.0134 
    3: NA NA NA NA NA NA -0.0978 NA -0.0908 -0.0206 
    4: NA NA NA NA NA NA -0.0445 NA -0.0269 -0.0287 
    5: NA NA NA NA NA NA 0.0139 NA 0.0298 -0.0141 
---                 
260: NA NA NA NA NA NA  NA NA  NA  NA 
261: NA NA NA NA NA NA  NA NA  NA  NA 
262: NA NA NA NA NA NA  NA NA  NA  NA 
263: NA NA NA NA NA NA  NA NA  NA  NA 
264: NA NA NA NA NA NA  NA NA  NA  NA 
> smallFundReturns[,1:10, with = FALSE] 
    33992 33261 38102 33264 33275 5606 41695 40483 41526 45993 
    1: NA NA NA NA NA NA NA NA NA NA 
    2: NA NA NA NA NA NA NA NA NA NA 
    3: NA NA NA NA NA NA NA NA NA NA 
    4: NA NA NA NA NA NA NA NA NA NA 
    5: NA NA NA NA NA NA NA NA NA NA 
---               
260: NA NA NA NA NA NA NA NA NA NA 
261: NA NA NA NA NA NA NA NA NA NA 
262: NA NA NA NA NA NA NA NA NA NA 
263: NA NA NA NA NA NA NA NA NA NA 
264: NA NA NA NA NA NA NA NA NA NA 

for (i in 1:nrow(allFundReturns)){ 
    theSubset <- as.vector(allFundReturns[i,] <= as.numeric(quantile(allFundAUM[i,], .5, na.rm = TRUE))) 
    theSubset[is.na(theSubset)] <- FALSE 
    theSubset <- colnames(allFundReturns)[theSubset] 
    smallFundReturns[i,theSubset, with = FALSE] = allFundReturns[i,theSubset, with = FALSE] 
} 

ich das Subset versuche mit for-Schleife (unter Verwendung einer for-Schleife in einem Versuch, zu debuggen):

for (i in 1:nrow(allFundReturns)){ 
    theSubset <- as.vector(allFundReturns[i,] <= as.numeric(quantile(allFundAUM[i,], .5, na.rm = TRUE))) 
    theSubset[is.na(theSubset)] <- FALSE 
    theSubset <- colnames(allFundReturns)[theSubset] 
    smallFundReturns[i,theSubset, with = FALSE] = allFundReturns[i,theSubset, with = FALSE] 
} 

Dies erzeugt einen Fehler:

Error in `[<-.data.table`(`*tmp*`, i, theSubset, with = FALSE, value = list(: 
    unused argument (with = FALSE) 

Ich versuchte, den ‚mit‘ Teil zu entfernen, aber das spuckt eine Reihe von Warnungen aus:

> warnings() 
Warning messages: 
1: In `[<-.data.table`(`*tmp*`, i, theSubset, value = c("41526", ... : 
    Supplied 3020 items to be assigned to 1 items of column '41526' (3019 unused) 
2: In `[<-.data.table`(`*tmp*`, i, theSubset, value = c("41526", ... : 
    Supplied 3020 items to be assigned to 1 items of column '45993' (3019 unused) 
3: In `[<-.data.table`(`*tmp*`, i, theSubset, value = c("41526", ... : 
    Supplied 3020 items to be assigned to 1 items of column '45994' (3019 unused) 
4: In `[<-.data.table`(`*tmp*`, i, theSubset, value = c("41526", ... : 

Ich bin verwirrt, wie dies zu tun. Irgendwelche Ideen darüber, wie ich die zweite data.table durch die Teilmenge auf der ersten unterteilen kann?

EDIT:

ich den Vorschlag unten versucht:

smallFundReturns[i,(theSubset):=allFundReturns[i,(theSubset), with = FALSE], with = FALSE] 

Und ich habe diese Warnungen():

> warnings() 
Warning messages: 
1: In `[.data.table`(smallFundReturns, i, `:=`((theSubset), ... : 
    Coerced 'double' RHS to 'logical' to match the column's type; may have truncated precision. Either change the target column to 'double' first (by creating a new 'double' vector length 264 (nrows of entire table) and assign that; i.e. 'replace' column), or coerce RHS to 'logical' (e.g. 1L, NA_[real|integer]_, as.*, etc) to make your intent clear and for speed. Or, set the column type correctly up front when you create the table and stick to it, please. 
2: In `[.data.table`(smallFundReturns, i, `:=`((theSubset), ... : 
    Coerced 'double' RHS to 'logical' to match the column's type; may have truncated precision. Either change the target column to 'double' first (by creating a new 'double' vector length 264 (nrows of entire table) and assign that; i.e. 'replace' column), or coerce RHS to 'logical' (e.g. 1L, NA_[real|integer]_, as.*, etc) to make your intent clear and for speed. Or, set the column type correctly up front when you create the table and stick to it, please. 
3: In `[.data.table`(smallFundReturns, i, `:=`((theSubset), ... : 

Und das diese erzeugt Code, mit 'TRUE' überall I würde eine Zahl erwarten:

EDIT 2:

Ich habe das Problem herausgefunden. Scheinbar ist diese Zeile:

smallFundReturns <- data.table(sapply(allFundReturns, function(x) rep(NA, length(x)))) 

erstellt die Tabelle als logisch. Habe ich es auf dieser Linie:

smallFundReturns <- data.table(sapply(allFundReturns, function(x) as.numeric(rep(NA, length(x))))) 

Und alles funktionierte nach @HubertL fix. Vielen Dank!!

Antwort

1

Sie haben es so schreiben:

smallFundReturns[i,(theSubset):=allFundReturns[i,(theSubset), with = FALSE], with = FALSE] 
+0

Das bringt 'TRUE' überall wo ich die Nummer erwarten würde. Ich schätze die Hilfe sehr, aber könntest du durchgehen, was das tun soll, damit ich herausfinden kann, warum "WAHR" statt der erwarteten Rückkehr auftaucht? – lukehawk

+0

Ich habe es herausgefunden. Vielen Dank! – lukehawk

+0

ziemlich sicher, dass die äußere 'mit = F' unnötig ist – eddi

1

Verbesserungsvorschläge:

Versuchen Lesen von Daten mit fread statt read.table, wenn möglich. Es ist viel schneller und das Ergebnis ist data.table nicht data.frame.

Wenn Sie "data.table operations" mit der Anweisung ", with = FALSE" ausführen, zwingen Sie R tatsächlich, die wesentlich langsameren data.frame-Operationen zu verwenden, anstatt die blitzschnellen data.table-Methoden zu verwenden.

Viel Spaß

+0

Danke! Ich wusste nicht, dass es eine Lesefunktion gab. Weißt du auch, wie ich das gleiche Ergebnis erzielen würde ohne mit? (Ich versuche nicht unhöflich zu klingen. Ich lerne immer noch das data.table-Paket.) Oder gibt es einen besseren Weg, dies alles gleichzeitig zu tun, ohne eine Schleife oder eine Anwendungsfunktion zu verwenden? Um nur die 25. Perzentil und schlechteren Werte jeder Spalte zu erhalten? – lukehawk

Verwandte Themen