2015-07-22 2 views
5

Рассмотрим следующий набор данных:Как предотвратить data.table, чтобы заставить числовые переменные в символьные переменные без указания вручную?

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)) 

Когда я хочу, чтобы разделить строки в последнем столбце в отдельные строки, я использую (с data.table версии 1.9.5+):

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

Однако, когда я использую:

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

Получаю тот же результат, за исключением того, что все col umns принудительно переходят в символьные переменные. Проблема в том, что для небольших наборов данных нет большой проблемы, чтобы указать переменные, которые не должны разбиваться на аргумент by, но для наборов данных со многими столбцами/переменными. Я знаю, что это можно сделать с пакетом splitstackshape (как упоминается @ColonelBeauvel in his answer), но я ищу решение data.table, так как хочу подключить к нему больше операций.

Как я могу предотвратить это, не указав вручную переменные, которые не должны быть разделены в аргументе by?

+6

Используйте аргумент 'type.convert = TRUE' для' tstrsplit() '. – Arun

+0

Если проблема заключается в указании большого количества переменных, можете ли вы использовать что-то вроде 'setdiff (names (dt), badcol)' для построения своих 'by' и' .SD'? – Frank

+2

@ Арун, который работал (и это звучит как ответ :-)) – Jaap

ответ

6

Два решения с data.table:

: Используйте type.convert=TRUE аргумент внутри tstrsplit(), предложенный @Arun:

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

: Используйте setdiff(names(dt),"places") в by аргумент, предложенный @Frank:

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

Оба подхода дают одинаковый результат:

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

Преимущество второго решения заключается в том, что, когда у вас есть больше thanone столбцы со строковыми значениями, только то, которое вы указываете в setdiff(names(dt),"places"), разделяется (предположим, что вы хотите только этот конкретный, в данном случае places, разделить). Этот пакет также предлагает пакет splitstackshape.

5

Это точно работа для cSplit из splitstackshape пакета:

library(splitstackshape) 

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

Thanx, я знаю, что могу сделать это с помощью 'splitstackshape' (но забыл упомянуть об этом в вопросе), но хотел получить решение' data.table' как хотите связать больше вещей с этим (+1 хотя). – Jaap

+3

@Jaap 'splitstackshape' является пакетом' data.table'. Но, конечно, Арун дал правильный ответ. Я удивлен, что вы этого не знали, хотя, поскольку мы обсуждали это в течение недели, когда я в конце концов опубликовал отчет об ошибке в отношении 'type.convert', и в конечном итоге он будет исправлен в следующей версии R :) –

+0

@Jaap, если вы можете импортировать 'data.table', вы можете импортировать' splitstackshape'! и вы можете управлять цепью после cSplit! –

Смежные вопросы