我想从列表中删除部分,以将列表缩减为具有一定列数的元素。
这是我正在尝试做的一个虚拟例子:
#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]]中的错误:下标越界。
是否有其他正确的方法?
答案 0 :(得分: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
的{{1}}是它拥有的列数
答案 1 :(得分:1)
对于tidyverse选项,您可以使用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 ...