2016-05-06 3 views
0

У меня есть df, YearHT, 6.5M x 55 столбцов. Существует определенная информация, которую я хочу извлечь и добавить, но только на основе совокупных значений. Я использую цикл for для подмножества большого df, а затем выполнения вычислений.альтернатива подмножеству в R

Я слышал, что для циклов следует избегать, и мне интересно, есть ли способ избежать цикла for, который я использовал, поскольку, когда я запускаю этот запрос, он занимает ~ 3 часа.

Вот мой код:

srt=NULL 
for(i in doubletCounts$Var1){ 
    s=subset(YearHT,YearHT$berthlet==i) 
    e=unlist(c(strsplit(i,'\\|'),median(s$berthtime))) 
    srt=rbind(srt,e) 
} 
srt=data.frame(srt) 
s2=data.frame(srt$X2,srt$X1,srt$X3) 
colnames(s2)=colnames(srt) 
s=rbind(srt,s2) 

doubletCounts составляет 700 х 3 ДФ, и каждое из значений находится в пределах большого ФР.

Я был бы рад услышать любые идеи по оптимизации/ускорению этого процесса.

+3

Не могли бы вы предоставить небольшой образец вашего набора данных, чтобы мы могли проверить код? Вы можете получить образец с помощью 'dput()' (убедитесь, что вы выбрали только первые 10 или около того) – Bas

+2

Поскольку вы работаете с очень большим набором данных, почему бы не попробовать 'data.table'? Это намного быстрее, чем кадры данных. –

ответ

2

Это быстрое решение, используя data.table, хотя с вашего вопроса не ясно, что нужно output.

# load library 
    library(datat.table) 

# convert your dataset into data.table 
    setDT(YearHT) 

# subset YearHT keeping values that are present in doubletCounts$Var1 
    YearHT_df <- YearHT[ berthlet %in% doubletCounts$Var1] 

# aggregate values 
    output <- YearHT_df[ , .(median= median(berthtime)) ] 
+0

Я определенно должен помнить о работе с таблицами данных, они намного быстрее. Я использовал их несколько раз, но всегда прибегаю к dfs. – alex

0

for Петли не обязательно должны быть чем-то, чего следует избегать, но есть определенные способы использования петлей for, которых следует избегать. Вы совершили классическую ошибку for.

srt = NULL 
for (i in index) 
{ 
    [stuff] 
    srt = rbind(srt, [stuff]) 
} 

обязан быть медленнее, чем хотелось бы, потому что каждый раз, когда вы попали srt = rbind(...), вы просите R, чтобы сделать все виды вещей, чтобы выяснить, какой тип объекта srt должен быть и сколько памяти выделите ему. Когда вы знаете, что длина вашего выхода должна быть впереди, это лучше сделать

srt <- vector("list", length = doubletCounts$Var1) 
for(i in doubletCounts$Var1){ 
    s=subset(YearHT,YearHT$berthlet==i) 
    srt[[i]] = unlist(c(strsplit(i,'\\|'),median(s$berthtime))) 
} 
srt=data.frame(srt) 

или apply альтернативу

srt = lapply(doubletCounts$Var1, 
     function(i) 
     { 
      s=subset(YearHT,YearHT$berthlet==i) 
      unlist(c(strsplit(i,'\\|'),median(s$berthtime))) 
     } 
) 

Оба эти должны работать примерно с той же скоростью

(Примечание: оба непроверены из-за отсутствия данных, поэтому они могут быть немного ошибочными)

Что-то еще вы можете попробовать, что может иметь меньший эффект, b e отбрасывая вызов subset и используйте индексирование. Содержание вашего for цикла может быть сводилось к

unlist(c(strsplit(i, '\\|'), 
     median(YearHT[YearHT$berthlet == i, "berthtime"]))) 

Но я не знаю, сколько времени, что позволит сэкономить.

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