R с изменением данных

Я пытаюсь изменить кадр данных в R, и, похоже, у него проблемы с использованием рекомендуемых способов. Кадр данных имеет следующую структуру:

ID                     DATE1             DATE2            VALTYPE        VALUE
'abcd1233'         2009-11-12        2009-12-23           'TYPE1'        123.45
...

VALTYPE является строкой и является фактором с двумя значениями (скажем TYPE1 и TYPE2). Мне нужно преобразовать его в следующий фрейм данных ( "широкий" транспонирование) на основе общих идентификаторов и DATE:

ID                     DATE1             DATE2            VALUE.TYPE1  VALUE.TYPE2
'abcd1233'             2009-11-12        2009-12-23       123.45           NA
...

Кадр данных имеет более 4,500,000 наблюдений (хотя около 70% VALUE составляют NA). Машина представляет собой рабочую станцию ​​Linux на базе Intel с 4 ГБ ОЗУ. Загрузка данных (из сжатого файла Rdata) в новый R-процесс приводит к тому, что он растет примерно до 250 Мб, что явно оставляет много места для перестройки.

Это мой опыт:

  • Использование метода ванили reshape():

    tbl2 < - reshape (tbl, direction = "wide", idvar = c ( "ID", "DATE1", "DATE2" ),               timevar = "VALTYPE" );

РЕЗУЛЬТАТ: Error: cannot allocate vector of size 4.8 Gb

  • Использование метода cast() пакета reshape:

    tbl2 < - cast (tbl, ID + DATE1 + DATE2 ~ VALTYPE);

РЕЗУЛЬТАТ: Процесс R потребляет всю ОЗУ без конца. Пришлось убить процесс в конце концов.

  • Использование by() и merge():

    sp < - by (tbl [c (1,2,3,5)], tbl $VALTYPE, функция (x) x); tbl <-merge (sp [[ "TYPE1" ]], sp [[ "TYPE2" ]],      by = c ( "ID", "DATE1", "DATE2" ), all = TRUE, sort = TRUE);

РЕЗУЛЬТАТ: работает отлично, хотя это не очень элегантно и надежно (т.е. оно будет ломаться, если добавлено больше типов).

Чтобы добавить оскорбление к травме, рассматриваемая операция может быть достигнута тривиально примерно в 3 строках AWK или Perl (и с едва ли используемой ОЗУ). Итак, вопрос в том, что лучший способ выполнить эту операцию в R с помощью рекомендуемых методов без использования всей доступной ОЗУ?

Ответ 1

Полезным трюком является объединение переменных id в вектор символов, а затем изменение формы.

tbl$NEWID <- with(tbl, paste(ID, DATE1, DATE2, sep=";"))
tbl2 <- recast(tbl2, NEWID ~ VALTYPE, measure.var="VALUE")

Это примерно на 40% быстрее в проблеме аналогичного размера в моей версии intel core2 duo 2.2ghz macbook.

Ответ 2

Как сделать это не-R-образным образом? Я предполагаю, что у вас есть строка TYPE1 и TYPE2 для каждого значения ID, DATE1, DATE2? Затем сортируйте dataframe по этим переменным и напишите большой цикл for. Вы можете многократно выполнять операции rbind() для построения таблицы, или вы можете попытаться заранее выделить таблицу (возможно) и просто назначить слоты VALUE.TYPE1 и VALUE.TYPE2 с помощью [< -, которые должны выполнять назначение в -место.

(Обратите внимание, что если вы используете rbind(), я считаю, что он неэффективен, если у вас есть какие-либо фактор-переменные, поэтому убедитесь, что все вместо символа!)

Ответ 3

Может быть, вы могли бы использовать функцию cat()?