如何在dplyr中对列表类型变量进行过滤?
如何用dplyr过滤列表类型的变量
这个问题我之前处理列表列的时候也踩过坑,咱们先搞清楚问题出在哪,再看正确的解决办法。
首先,你遇到的第一个问题:aa %>% filter(is.logical(dd))返回空框,是因为dd是列表列,is.logical(dd)判断的是整个列的类型(列表类型),而不是列表里每个元素的类型。你提到的aa$dd[1]其实还是一个长度为1的列表,只有用[[1]]才能取到列表里的实际元素,所以要逐个检查每个列表元素的类型才行。
然后你尝试用map直接放到filter里报错,原因是purrr::map返回的是一个列表(每个元素对应一行的判断结果),但dplyr::filter需要的是一个和数据框行数一致的逻辑向量,不是列表,所以会抛出错误。
正确的实现方式
我们需要把map的结果转换成逻辑向量,这里用purrr::map_lgl就可以(后缀_lgl表示返回逻辑向量):
library(dplyr) library(purrr) aa <- tibble(ss = c(1,2), dd = list(NA, matrix(data = c(1,2,3,4), nrow = 2, ncol = 2))) # 筛选dd元素为logical类型的行 aa %>% filter(map_lgl(dd, is.logical))
运行后会得到预期结果:
# A tibble: 1 × 2 ss dd <dbl> <list> 1 1 <lgl [1]>
替代方案:用base R的sapply
如果你不想加载purrr,用base R的sapply也能实现,因为sapply默认会把列表结果简化成向量:
aa %>% filter(sapply(dd, is.logical))
这个写法也能得到和上面一样的结果。
额外说明
如果要筛选其他类型的列表元素,比如矩阵,可以把is.logical换成is.matrix,同样用map_lgl或者sapply就行,逻辑是一样的:
# 筛选dd元素为矩阵的行 aa %>% filter(map_lgl(dd, is.matrix))
内容的提问来源于stack exchange,提问作者Scransom
相关产品推荐
相关产品推荐

