从列表中子集满足条件的某些数据帧

时间:2018-02-01 22:39:48

标签: r list subset

我刚开始使用列表和lapply函数,我遇到了一些困难。我有一个包含多个数据帧的列表,并希望对满足特定条件的数据帧进行子集化,并将其另存为单独的列表。例如,

l <- list(data.frame(PPID=1:5, gender=c(rep("male", times=5))),
          data.frame(PPID=1:5, gender=c("male", "female", "male", "male", "female")), 
          data.frame(PPID=1:3, gender=c("male", "female", "male")))

print(l)

我想要做的是仅将具有性别(男性和女性)的列表分组,并将其另存为另一个列表。所以我的结果应该是另一个列表,其中只包含l。

中的第二和第三个数据帧

我尝试过的事情包括:

ll <- subset(l, lapply(1:length(l), function(i) { 
      length(levels(l[[i]]$gender)) == 2
      }))

ll <- subset(l, lapply(1:length(l), function(i) { 
      l[[i]]$gender == "male" | l[[i]]$gender == "female"
      }))

但这给了我一个0的清单。 任何帮助将不胜感激!!

2 个答案:

答案 0 :(得分:2)

如果您愿意切换到purrr,您可以简单地:

> library(purrr)
> keep(l, ~ length(unique(.x$gender)) > 1)
[[1]]
  PPID gender
1    1   male
2    2 female
3    3   male
4    4   male
5    5 female

[[2]]
  PPID gender
1    1   male
2    2 female
3    3   male

答案 1 :(得分:2)

这适用于基础R:

   lapply(l, function(x) if (length(unique(x$gender)) == 2) x)
   #[[1]]
   #NULL
   #
   #[[2]]
   #  PPID gender
   #1    1   male
   #2    2 female
   #3    3   male
   #4    4   male
   #5    5 female
   #
   #[[3]]
   #  PPID gender
   #1    1   male
   #2    2 female
   #3    3   male

如果您不想保留NULL条目,可以执行

l2 <- lapply(l, function(x) if (length(unique(x$gender)) == 2) x)
Filter(Negate(is.null), l2);

您的代码存在的一个问题是虽然genderfactor,但它在所有列表元素中没有相同的levels。你可以查看:

str(l);
#List of 3
# $ :'data.frame':  5 obs. of  2 variables:
#  ..$ PPID  : int [1:5] 1 2 3 4 5
#  ..$ gender: Factor w/ 1 level "male": 1 1 1 1 1
# $ :'data.frame':  5 obs. of  2 variables:
#  ..$ PPID  : int [1:5] 1 2 3 4 5
#  ..$ gender: Factor w/ 2 levels "female","male": 2 1 2 2 1
# $ :'data.frame':  3 obs. of  2 variables:
#  ..$ PPID  : int [1:3] 1 2 3
#  ..$ gender: Factor w/ 2 levels "female","male": 2 1 2