Как удалить пустые фреймы данных из списка?

У меня есть десятки списков, каждый из которых представляет собой набор из 11 кадров данных. Некоторые кадры данных пустые (другой script не выводил никаких данных, а не ошибки).

Мне нужно вытолкнуть каждый список через функцию, но это дросселирует, когда видит пустой фрейм данных. Итак, как мне написать функцию, которая возьмет список, понизьте каждый элемент (т.е. Кадр данных), а если он 0, перейдите к следующему.

Я пробовал что-то вроде этого:

empties <- function (mlist)
{
 for(i in 1:length(mlist))
   {
    if(dim(mlist[[i]])[1]!=0) return (mlist[[i]])
    }
}

Но ясно, что это не сработало. Я бы сделал это вручную в этот момент, но это займет навсегда. Помощь?

Ответы

Ответ 1

Я не уверен, что это именно то, о чем вы просите, но если вы хотите обрезать mlist вниз, чтобы содержать только непустые кадры данных, прежде чем запускать на нем функцию, попробуйте mlist[sapply(mlist, function(x) dim(x)[1]) > 0].

например:.

R> M1 <- data.frame(matrix(1:4, nrow = 2, ncol = 2))
R> M2 <- data.frame(matrix(nrow = 0, ncol = 0))
R> M3 <- data.frame(matrix(9:12, nrow = 2, ncol = 2))
R> mlist <- list(M1, M2, M3)
R> mlist[sapply(mlist, function(x) dim(x)[1]) > 0]
[[1]]
  X1 X2
1  1  3
2  2  4

[[2]]
  X1 X2
1  9 11
2 10 12

Ответ 2

Несколько более простой и более прозрачный подход к комбинации sapply/indexing заключается в использовании функции Filter():

> Filter(function(x) dim(x)[1] > 0, mlist)
[[1]]
  X1 X2
1  1  3
2  2  4

[[2]]
  X1 X2
1  9 11
2 10 12

Ответ 3

Добавление опции Tidyverse:

library(tidyverse)
mlist[map(mlist, function(x) dim(x)[1]) > 0]


mlist[map(mlist, ~dim(.)[1]) > 0]

Ответ 4

Вместо dim(x)[1] вы можете использовать nrow, чтобы вы могли сделать

mlist[sapply(mlist, nrow) > 0]

Filter(function(x) nrow(x) > 0, mlist)

Вы также можете использовать keep и discard от purrr

purrr::keep(mlist, ~nrow(.) > 0)
purrr::discard(mlist, ~nrow(.) == 0)

Если вы можете фильтровать список по количеству столбцов, вы можете заменить nrow на ncol в ответах выше. Кроме того, вы также можете использовать lengths для фильтрации списка.

mlist[lengths(mlist) > 0]