Использование apply на больших ffdfs

Основная идея такова: у меня есть большое ffdf (около 5,5 миллионов x 136 полей). Я точно знаю, что некоторые из этих столбцов в этом фрейме данных имеют столбцы, которые все NA. Как мне узнать, какие из них и удалить их соответствующим образом?

Мой инстинкт состоит в том, чтобы сделать что-то вроде (при условии, что df это ffdf):

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 не может обрабатывать фрейм данных такого размера. Есть ли альтернативы, которые я могу использовать?


person Clarinetist    schedule 01.12.2015    source источник
comment
Как насчет просто df[, !colSums(is.na(df[,1:136]))==nrow(df)] ?   -  person zx8754    schedule 01.12.2015
comment
@ zx8754 zx8754 Вы имеете в виду colSums вместо этого (см. Мое предыдущее редактирование)? В любом случае, я все еще получаю ту же ошибку.   -  person Clarinetist    schedule 01.12.2015
comment
@zx8754 zx8754 Только что увидел вашу правку, попробую   -  person Clarinetist    schedule 01.12.2015
comment
@zx8754 zx8754 Тем не менее, мне было бы интересно получить список удаленных столбцов, но я полагаю, это не будет слишком сложно ... просто сравните names.   -  person Clarinetist    schedule 01.12.2015


Ответы (2)


Проще использовать all(is.na(column)). sapply/lapply не работают, потому что и 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]
person Jan van der Laan    schedule 01.12.2015
comment
Аналогичная ошибка при объявлении cols: Warning messages: 1: In ff::[.ff(x = x, i = i, pack = pack) : Reached total allocation of 3889Mb: see help(memory.size) 2: In ff::[.ff(x = x, i = i, pack = pack) : Reached total allocation of 3889Mb: see help(memory.size)] - person Clarinetist; 01.12.2015
comment
@Clarinetist Я видел обсуждение в комментариях под вашим вопросом и изменил свой ответ. Ваша ошибка вызвана тем, что ваш код считывает полный набор данных в память. - person Jan van der Laan; 01.12.2015
comment
cols сработало, df[, !cols] выдал аналогичную ошибку. - person Clarinetist; 01.12.2015
comment
Я не уверен, было ли это намерением, но cols имеет только два значения: под virtual: FALSE и под physical: FALSE. - person Clarinetist; 01.12.2015
comment
@Кларнетист Вы правы. sapply не работает. Игрушечный пример, который я использовал для проверки кода, сработал, потому что у меня случайно оказалось то же количество столбцов, что и sapply. Мой новый код не должен работать. - person Jan van der Laan; 01.12.2015
comment
Очень хорошо. Благодарю вас! - person Clarinetist; 01.12.2015

Попробуйте этот пример:

#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"
person zx8754    schedule 01.12.2015
comment
С моей стороны работает нормально. - person Clarinetist; 01.12.2015