Функции для создания и изменения больших данных в R с помощью пакета FF

Я новичок в R и пакете FF и пытаюсь лучше понять, как FF позволяет пользователям работать с большими наборами данных (> 4 ГБ). Я провел значительное количество времени в Интернете в поисках учебных пособий, но те, которые я мог найти, как правило, выходят за рамки моей головы.

Я лучше всего учусь на практике, поэтому в качестве упражнения я хотел бы знать, как создать набор данных длинного формата временных рядов, аналогичный встроенному в R набору данных «Indometh», используя произвольные значения. Затем я хотел бы изменить его в широкий формат. Затем я хотел бы сохранить вывод в виде файла csv.

С небольшими наборами данных это просто и может быть достигнуто с помощью следующего скрипта:

##########################################
#Generate the data frame

DF<-data.frame()
for(Subject in 1:6){
  for(time in 1:11){
    DF<-rbind(DF,c(Subject,time,runif(1)))
  }
}
names(DF)<-c("Subject","time","conc")

##########################################
#Reshape to wide format

DF<-reshape(DF, v.names = "conc", idvar = "Subject", timevar = "time", direction = "wide")

##########################################
#Save csv file

write.csv(DF,file="DF.csv")

Но я хотел бы научиться делать это для файлов размером примерно 10 Гб. Как бы я сделал это, используя пакет FF? Заранее спасибо.


person Luke23    schedule 31.01.2014    source источник


Ответы (2)


Функция reshape явно не существует для объектов ffdf. Но это довольно просто выполнить с помощью функций из пакета ffbase. Просто используйте ffdfdply из пакета ffbase, разделите по темам и примените reshape внутри функции.

Пример набора данных Indometh с 1 000 000 субъектов.

require(ffbase)
require(datasets)
data(Indometh)

## Generate some random data
x <- expand.ffgrid(Subject = ff(factor(1:1000000)), time = ff(unique(Indometh$time)))
x$conc <- ffrandom(n=nrow(x), rfun = rnorm)
dim(x)
[1] 11000000        3

## and reshape to wide format
result <- ffdfdply(x=x, split=x$Subject, FUN=function(datawithseveralsplitelements){
  df <- reshape(datawithseveralsplitelements, 
              v.names = "conc", idvar = "Subject", timevar = "time", direction = "wide")
  as.data.frame(df)
})
class(result)
[1] "ffdf"
colnames(result)
[1] "Subject"   "conc.0.25" "conc.0.5"  "conc.0.75" "conc.1"    "conc.1.25" "conc.2"    "conc.3"    "conc.4"    "conc.5"    "conc.6"    "conc.8"   
dim(result)
[1] 1000000      12
person Community    schedule 31.01.2014
comment
Спасибо за ваш полезный ответ. - person Luke23; 03.02.2014

Вам было бы трудно создать менее эффективный метод, чем тот, который вы предлагаете. Использование rbind.data.frame невероятно неэффективно. Вместо этого попробуйте создать набор данных из шести тысяч строк для 6 субъектов:

DF <- data.frame( Subj = rep( 1:6, each=1000), matrix(runif(6000*11), nrow=6000) )

Масштабирование до миллиарда элементов (миллиардов долларов США, а не миллиардов Великобритании) должно дать вам объект размером около 10 ГБ, так что, может быть, попробовать 80 миллионов строк или около того?

Я думаю, что запрос учебника в ff-пакете выходит за рамки SO. Пожалуйста, прочтите FAQ. Такие вопросы обычно закрыты, потому что спрашивающий демонстрирует, что на самом деле не знает, о чем говорит.

person IRTFM    schedule 31.01.2014
comment
Во-вторых, вы явно не читали мой вопрос. Я не просил туториал в фф-пакете. Я спросил, как выполнить очень конкретную задачу. Ваш ответ показывает, что вы не понимаете, как выполнить эту задачу. - person Luke23; 03.02.2014
comment
Что ж, я прочитал вопрос, как видно из моих усилий по кодированию. Но я признаю, что не знал о невероятно компактном решении, которое jwiffels предоставил ffdfdply. Так что, думаю, я просто проголосую за вас обоих. - person IRTFM; 05.02.2014