Как удалить пустые фреймы данных из списка? - PullRequest
20 голосов
/ 16 июля 2010

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

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

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

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

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

Ответы [ 4 ]

24 голосов
/ 16 июля 2010

Я не уверен, что это именно то, что вы запрашиваете, но если вы хотите урезать 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
13 голосов
/ 16 июля 2010

Немного более простой и прозрачный подход к комбинации 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
1 голос
/ 13 июня 2019

Вместо 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)

В purrr также есть compact, который удаляет все пустые элементы напрямую.Это оболочка для discard

purrr::compact(mlist)

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

mlist[lengths(mlist) > 0]
1 голос
/ 02 мая 2019

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

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


mlist[map(mlist, ~dim(.)[1]) > 0]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...