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

Вот пример того, что я пытаюсь сделать:

    #1: define the list
    tables = list(mtcars,iris)

    for(k in 1:length(tables)) {
      # 2: be sure that each element is shaped as dataframe and not matrix
      tables[[k]] = as.data.frame(tables[[k]])
      # 3: remove elements that have more or less than 5 columns
      if(ncol(tables[[k]]) != 5) {
        tables <- tables[-k]
      }
    }

Другой вариант я попробовал:

    #1: define the list
    tables = list(mtcars,iris)

    for(k in 1:length(tables)) {
      # 2: be sure that each element is shaped as dataframe
      tables[[k]] = as.data.frame(tables[[k]])
      # 3: remove elements that have more or less than 5 columns
      if(ncol(tables[[k]]) != 5) {
        tables[[-k]] <- NULL
      }
    }

Я получаю

Ошибка в таблицах [[k]]: нижний индекс за пределами.

Есть ли альтернативный и правильный подход?

3
pachamaltese 27 Май 2017 в 20:22

2 ответа

Лучший ответ

Мы можем использовать Filter

Filter(function(x) ncol(x)==5, tables)

Или с sapply для создания логического индекса и подмножества list

tables[sapply(tables, ncol)==5]

Или как прокомментировал @Sotos

tables[lengths(tables)==5]

lengths возвращает length каждого элемента list, преобразует его в логический вектор и задает подмножество list. length для data.frame - это количество столбцов

2
akrun 27 Май 2017 в 19:29

Для варианта перехода можно использовать purrr:keep. Вы просто определяете функцию предиката, если true, он сохраняет элемент списка, если false, он удаляет его. Здесь я сделал это с помощью опции формулы.


library(purrr)

tables <- list(mtcars, iris)

result <- purrr::keep(tables, ~ ncol(.x) == 5)

str(result)

#> List of 1
#>  $ :'data.frame':    150 obs. of  5 variables:
#>   ..$ Sepal.Length: num [1:150] 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
#>   ..$ Sepal.Width : num [1:150] 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
#>   ..$ Petal.Length: num [1:150] 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
#>   ..$ Petal.Width : num [1:150] 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
#>   ..$ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
1
austensen 27 Май 2017 в 22:54