如何在调用bind_rows()前清理列表中的空数据框、tibble及空列表?
嗨,我来帮你搞定这个问题!咱们一步步来解决你的需求:
1. 移除列表中的tibble和空列表,保留普通dataframe再合并
首先你提到的delete.NULLs并不是R内置或tidyverse里的标准函数,难怪会报错~咱们用基础R或者tidyverse的工具就能轻松实现筛选:
方法一:用tidyverse的purrr::keep()
library(dplyr) library(purrr) # 假设你的混合列表叫my_list filtered_list <- my_list %>% keep(function(item) { # 两个筛选条件:不是tibble,并且不是空列表 !inherits(item, "tbl_df") && length(item) != 0 }) # 合并剩余的dataframe combined_df <- bind_rows(filtered_list)
方法二:用基础R的Filter()
如果不想加载purrr,用基础R也能搞定:
filtered_list <- Filter(function(item) { !inherits(item, "tbl_df") && length(item) != 0 }, my_list) # 合并(用bind_rows或者基础R的do.call(rbind, ...)都可以) combined_df <- bind_rows(filtered_list)
2. 移除列表中的空dataframe(包括空tibble)
如果要在合并前去掉空的dataframe(不管是普通df还是tibble),可以这样操作:
方法一:保留非空的df/tibble,同时保留其他非空元素(如果有的话)
filtered_no_empty <- my_list %>% keep(function(item) { # 如果是dataframe/tibble,就判断行数大于0;否则保留非空元素 if (inherits(item, c("data.frame", "tbl_df"))) { nrow(item) > 0 } else { length(item) != 0 } }) combined_df <- bind_rows(filtered_no_empty)
方法二:直接丢弃空的df/tibble
用purrr::discard()会更简洁:
filtered_no_empty <- my_list %>% discard(function(item) { # 判断是df/tibble且为空 inherits(item, c("data.frame", "tbl_df")) && nrow(item) == 0 }) combined_df <- bind_rows(filtered_no_empty)
小提示
- tibble本质是
tbl_df类的dataframe,所以is.data.frame(tibble())会返回TRUE,如果要区分普通df和tibble,必须用inherits(item, "tbl_df")来判断。 - 空列表可以用
length(item) == 0或者purrr::is_empty(item)来识别,两者效果一致。
内容的提问来源于stack exchange,提问作者Jane
相关产品推荐
相关产品推荐

