从 R 中的 tibble 中删除空列表

Remove empty lists from a tibble in R

我正在尝试从我的小标题中删除任何包含“

的列表
library(tidyverse)

df <- tibble(x = 1:3, y = list(as.character()), 
             z=list(as.character("ATC"),as.character("TAC"), as.character()))
df
#> # A tibble: 3 × 3
#>       x y         z        
#>   <int> <list>    <list>   
#> 1     1 <chr [0]> <chr [1]>
#> 2     2 <chr [0]> <chr [1]>
#> 3     3 <chr [0]> <chr [0]>

reprex package (v2.0.1)

创建于 2022-02-15

我希望我的标题看起来像这样

#> # A tibble: 3 × 3
#>       x  z        
#>    <int> <list>   
#> 1     1 <chr [1]>
#> 2     2 <chr [1]>
#> 3     3    NA

感谢任何帮助

你可以这样做:

df %>%
  select(where(~!all(lengths(.) == 0))) %>%
  mutate(z = lapply(z, function(x) ifelse(length(x) == 0, NA, x)))

# A tibble: 3 x 2
      x z        
  <int> <list>   
1     1 <chr [1]>
2     2 <chr [1]>
3     3 <lgl [1]>

请注意,在您的 z 列中,您不能有第 1 行和第 2 行的列表元素和直接逻辑值 NA。整列需要是一个列表。

如果z的所有元素只有一个元素,可以再添加一行代码mutate(z = unlist(z))


TO 要求更动态的解决方案来传递多个列。

这是我简单地创建了另一个 z2 变量的例子。通常,您可以使用 across.

对多个列重复重新编码
library(tidyverse)

df <- tibble(x = 1:3, y = list(as.character()), 
             z=list(as.character("ATC"),as.character("TAC"), as.character()),
z2 = z)

df %>%
  select(where(~!all(lengths(.) == 0))) %>%
  mutate(across(starts_with('z'), ~ lapply(., function(x) ifelse(length(x) == 0, NA, x))))

给出:

# A tibble: 3 x 3
      x z         z2       
  <int> <list>    <list>   
1     1 <chr [1]> <chr [1]>
2     2 <chr [1]> <chr [1]>
3     3 <lgl [1]> <lgl [1]>

A two-step 使用基数 R 的方法:

df <- tibble(x = 1:3, y = list(as.character()), 
             z=list(as.character("ATC"),as.character("TAC"), as.character()))


df <- df[apply(df, 2, function(x) any(lapply(x, length) > 0))] #Remove empty columns
df[apply(df, 2, function(x) lapply(x, length) == 0)] <- NA #Replace empty lists with NA

df
# A tibble: 3 x 2
      x z        
  <int> <list>   
1     1 <chr [1]>
2     2 <chr [1]>
3     3 <NULL>