2015-07-22 3 views
5

Betrachten Sie die folgende Datenmenge:Wie kann verhindert werden, dass data.table numerische Variablen in Zeichenvariablen erzwingt, ohne diese manuell anzugeben?

dt <- structure(list(lllocatie = structure(c(1L, 6L, 2L, 4L, 3L), .Label = c("Assen", "Oosterwijtwerd", "Startenhuizen", "t-Zandt", "Tjuchem", "Winneweer"), class = "factor"), 
       lat = c(52.992, 53.32, 53.336, 53.363, 53.368), 
       lon = c(6.548, 6.74, 6.808, 6.765, 6.675), 
       mag.cat = c(3L, 2L, 1L, 2L, 2L), 
       places = structure(c(2L, 4L, 5L, 6L, 3L), .Label = c("", "Amen,Assen,Deurze,Ekehaar,Eleveld,Geelbroek,Taarlo,Ubbena", "Eppenhuizen,Garsthuizen,Huizinge,Kantens,Middelstum,Oldenzijl,Rottum,Startenhuizen,Toornwerd,Westeremden,Zandeweer", "Loppersum,Winneweer", "Oosterwijtwerd", "t-Zandt,Zeerijp"), class = "factor")), 
      .Names = c("lllocatie", "lat", "lon", "mag.cat", "places"), 
      class = c("data.table", "data.frame"), 
      row.names = c(NA, -5L)) 

Wenn ich die Saiten in der letzten Spalte in einzelne Zeilen aufteilen möchten, verwende ich (mit data.table Version 1.9.5+):

dt.new <- dt[, lapply(.SD, function(x) unlist(tstrsplit(x, ",", fixed=TRUE))), by=list(lllocatie,lat,lon,mag.cat)] 

Allerdings, wenn ich verwenden:

dt.new2 <- dt[, lapply(.SD, function(x) unlist(tstrsplit(x, ",", fixed=TRUE))), by=lllocatie] 

ich das gleiche Ergebnis, außer dass alle col erhalten Umns werden in Zeichenvariablen gezwungen. Das Problem ist, dass es für kleine Datasets kein großes Problem ist, die Variablen anzugeben, die nicht in das by Argument aufgeteilt werden müssen, sondern für Datasets mit vielen Spalten/Variablen. Ich weiß, dass es möglich ist, dies mit dem splitstackshape Paket zu tun (wie von @ColonelBeauvel in his answer erwähnt), aber ich bin auf der Suche nach einer data.table Lösung, wie ich mehr Operationen daran ketten wollen.

Wie kann ich das verhindern, ohne manuell die Variablen anzugeben, die nicht im by Argument aufgeteilt werden müssen?

+6

Verwenden Sie das 'type.convert = TRUE'-Argument für' tstrsplit() '. – Arun

+0

Wenn es ein Problem ist, viele Variablen anzugeben, können Sie etwas wie 'setdiff (names (dt), badcol)' verwenden, um 'by' und' .SD' zu konstruieren? – Frank

+2

@Arun, das funktioniert (und es klingt wie eine Antwort :-)) – Jaap

Antwort

6

Zwei Lösungen mit data.table:

: Verwenden Sie das type.convert=TRUE Argument innerhalb tstrsplit() wie @Arun vorgeschlagen:

dt.new1 <- dt[, lapply(.SD, function(x) unlist(tstrsplit(x, ",", fixed=TRUE, type.convert=TRUE))), by=lllocatie] 

: Verwenden Sie setdiff(names(dt),"places") im by Argument von @Frank vorgeschlagen:

dt.new2 <- dt[, lapply(.SD, function(x) unlist(tstrsplit(x, ",", fixed=TRUE))), by=setdiff(names(dt),"places")] 

Beide Ansätze das gleiche Ergebnis:

> identical(dt.new1,dt.new2) 
[1] TRUE 

Der Vorteil der zweiten Lösung besteht darin, dass, wenn Sie mehr thanone haben Spalten mit Zeichenfolgenwerten, nur die, die Sie in setdiff(names(dt),"places") angeben, wird aufgeteilt (vorausgesetzt, Sie möchten nur diese bestimmte, in diesem Fall places, teilen). Das Paket splitstackshape bietet auch diesen Vorteil.

5

Es ist genau ein Job für cSplit vom splitstackshape Paket:

library(splitstackshape) 

cSplit(dt, 'places', ',') 
+0

Danke, ich weiß, ich kann das mit 'splitstapshape' (aber vergessen, das in der Frage zu erwähnen), aber wollte eine' data.table' Lösung als möchte mehr Sachen dazu ketten (ein +1 obwohl). – Jaap

+3

@Jaap das 'splitstapshape' ist ein' data.table'-basiertes Paket. Aber natürlich lieferte Arun die richtige Antwort. Ich bin überrascht, dass du das nicht gewusst hast, als wir das über eine Woche lang diskutierten, als ich schließlich einen Fehlerbericht bezüglich 'type.convert' einreichte und dieser schließlich in der nächsten Version von R behoben werden würde: –

+0

@Jaap, Wenn Sie 'data.table' importieren können, können Sie' splatstapshape' importieren! und Sie können den Betrieb nach dem cSplit! –

Verwandte Themen