2015-12-01 24 views
3

基本思路是這樣的:我有一個大的ffdf(約550萬x 136字段)。我知道這個數據框中的一些列有全部是NA的列。我如何找出哪些和適當地刪除它們?使用適用於大ffdfs

我的直覺是像做(假設dfffdf):

apply(X=is.na(df[,1:136]), MARGIN = 2, FUN = sum)

應該給我NA數爲每列向量,然後我可以找到哪些具有〜5.5百萬NA值,刪除它們使用df <- df[,-c(vector of columns)]等。非常簡單。

但是,apply給了我一個錯誤。

Error: cannot allocate vector of size 21.6 Mb 
In addition: Warning messages: 
1: In `[.ff`(p, i2) : 
    Reached total allocation of 3889Mb: see help(memory.size) 
2: In `[.ff`(p, i2) : 
    Reached total allocation of 3889Mb: see help(memory.size) 
3: In `[.ff`(p, i2) : 
    Reached total allocation of 3889Mb: see help(memory.size) 
4: In `[.ff`(p, i2) : 
    Reached total allocation of 3889Mb: see help(memory.size) 

這告訴我,apply無法處理這種規模的數據幀。有什麼替代方案可以使用嗎?

+0

如何只'DF [,colSums(is.na(DF [1:136]))!== nrow(DF)]'? – zx8754

+0

@ zx8754你的意思是'colSums'(請參閱我以前的編輯)?無論哪種方式,我仍然得到同樣的錯誤。 – Clarinetist

+0

@ zx8754剛剛看到你的編輯,會嘗試 – Clarinetist

回答

1

它更易於使用all(is.na(column))。因爲ffdf對象不是列表。

您在代碼中使用df[, 1:136]。這將導致ff嘗試將全部136列加載到內存中。這是導致內存問題的原因。當你做df[1:136]時,這不會發生。索引最終結果時會發生同樣的情況:df <- df[,-c(vector of columns)]將所有選定列讀入內存。

na_cols <- logical(136) 
for (i in seq_len(136)) { 
    na_cols[i] <- all(is.na(df[[i]])) 
} 

res <- df[!na_cols] 
+0

聲明'cols'時出現類似錯誤:'警告訊息: 1:在ff ::'[.ff'(x = x,i = i,pack = pack)中: 達到3889Mb的總分配: .size) 2:在ff ::'[.ff'(x = x,i = i,pack = pack)中: 達到3889Mb的總分配:見help(memory.size)' – Clarinetist

+0

@Clarinetist我看到討論你的問題下的意見,並修改我的答案。您的錯誤是由於您的代碼將完整的數據集讀入內存引起的。 –

+0

'cols'工作,'df [,!cols]'給了我一個類似的錯誤。 – Clarinetist

0

試試這個例子:

#dummy data 
df <- sample(1000000*5) 
df <- data.frame(matrix(df,nrow = 1000000)) 
df$X3 <- NA 
df$X6 <- NA 

#list of col to remove or keep 
colToRemove <- colnames(df)[ colSums(is.na(df[ ,1:6])) == nrow(df) ] 
colToKeep <- setdiff(colnames(df), colToRemove) 

#subset 
res <- df[, colToKeep] 

colnames(df) 
#[1] "X1" "X2" "X3" "X4" "X5" "X6" 
colnames(res) 
#[1] "X1" "X2" "X4" "X5" 
+0

我的工作很好。 – Clarinetist