【问题标题】:How can i ignore all empty cells in a df, without dropping entire rows / columns?如何忽略 df 中的所有空单元格,而不删除整个行/列?
【发布时间】:2019-09-19 14:23:38
【问题描述】:

我的数据如下所示:

Screenshot of what I have

我希望忽略/删除所有空单元格,删除整个行或列,以实现如下目的:

Screenshot of what I want

对于每一列,我想获取它包含的所有值(在顶部组合在一起),跳过任何空的单元格。我尝试了各种 tidyverse 解决方案(选择、过滤器),但运气不佳 - 我有 x816 列,所以我需要一个可以应用于整个 df 而不是显式命名的列的解决方案。

我知道这很不寻常,并且一行中的所有观察结果通常都捆绑在一起(例如,每个参与者一行),但在这种特殊情况下,行信息是否跨列不同并不重要。

任何帮助将不胜感激!

【问题讨论】:

  • 您的数据不属于 data.frame,因为它(至少是预期结果)不是表格的。因此,结果应该是一个列表。如果你有一个data.frame DF,你可以做res <- lapply(DF, function(x) x[!is.na(x)])

标签: r select tidyverse


【解决方案1】:

1)这是一种不使用任何包的单行解决方案。

在每个列上使用 na.omit 将每个列转换为 ts 类。 cbind 然后会自动处理不同的长度。末尾的 [TRUE, ] 删除了 ts 类。

# test input
DF <- data.frame(V1 = c("a1", NA, "a2"), V2 = c(NA, NA, "a3"), 
   V3 = c("a4", NA, NA), stringsAsFactors = FALSE)

res1 <- do.call("cbind", lapply(DF, function(x) ts(na.omit(x))))[TRUE, ]

给出这个矩阵:

> res1
     V1   V2   V3  
[1,] "a1" "a3" "a4"
[2,] "a2" NA   NA  

如果您更喜欢数据框结果,请使用:

as.data.frame(res1, stringsAsFactors = FALSE)

2) 这是另一种解决方案,也是一条线,不使用任何包。它省略了 NA,然后将结果向量扩展到所需的行数。最后将其塑造成一个 data.frame。

res2 <- replace(DF, TRUE, lapply(DF, function(x) `length<-`(na.omit(x), nrow(DF))))

给出这个data.frame:

> res2
    V1   V2   V3
1   a1   a3   a4
2   a2 <NA> <NA>
3 <NA> <NA> <NA>

这个略有不同,因为它生成一个 data.frame 而不是一个矩阵,并且它使生成的 data.frame 与输入具有相同的维度。如果您想删除全部为 NA 的行,那么

res2[rowSums(!is.na(res)) > 0, ]
##   V1   V2   V3
## 1 a1   a3   a4
## 2 a2 <NA> <NA>

【讨论】:

  • 这些工作完美——第一个解决方案正是我所寻找的。非常感谢!
【解决方案2】:

你可以试试这样的

library(tidyverse)
set.seed(1234)


df <- tibble(
  v1 = sample(c(letters[1:4], rep(NA, 20)), 20, replace = TRUE),
  v2 = sample(c(letters[1:4], rep(NA, 20)), 20, replace = TRUE),
  v3 = sample(c(letters[1:4], rep(NA, 20)), 20, replace = TRUE),
  v4 = sample(c(letters[1:4], rep(NA, 20)), 20, replace = TRUE)
)


df %>% 
  fill(names(df)) %>% 
  distinct()

如果您不关心组合并且只想要唯一值,您可以这样做:

df %>% 
  gather() %>% 
  distinct(key, value) %>% 
  filter(!is.na(value)) %>% 
  group_by(key) %>% 
  arrange(value) %>% 
  mutate(ord = row_number()) %>% 
  ungroup() %>% 
  spread(key, value)

#   ord v1    v2    v3    v4   
#     1 b     b     b     c    
#     2 d     c     NA    NA   
#     3 NA    d     NA    NA 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多