按组 [duplicate] 删除 NA

Remove NAs by group [duplicate]

提问人:Gabriela Zuquim 提问时间:11/3/2023 最后编辑:M--Gabriela Zuquim 更新时间:11/3/2023 访问量:86

问:

在 R 中: 我有数据帧测试,想要数据帧测试总和。基本上采用列的文本并按组删除 nas

test <- data.frame(
   Group = c("A", "A", "B", "B", "C"),
   Text = c("Apple", NA, "Cherry", NA, "Grape"),
    Text2 = c(NA, "Banana", NA, "Cherry", NA)
    )


testsumm<-data.frame(
  Group = c("A","B","C"),
  Text = c("Apple", "Cherry", "Grape"),
 Text2 = c( "Banana",  "Cherry", NA))

我的真实数据很大(>5000 行和 30 列),所以我需要一个自动解决方案。谢谢!

r dplyr na

评论

1赞 PGSA 11/3/2023
是否保证每个都只有一个有效和一个有效?你的第三组没有 - 这在你的真实数据集中可能吗?GroupTextText2Text2
0赞 Gabriela Zuquim 11/3/2023
是的!对于每个组,每个“文本”列中只有一个水果。每组可以有一个或多个水果。C 组只有一个水果,所以 Text2 是 NA
0赞 PGSA 11/3/2023
@M-- 链接的线程并不完全相同,因为这需要考虑两个变量 - IMO 是否有足够的差异来保证重新开放?
0赞 M-- 11/3/2023
@PaulStaffordAllen 我看到的所有区别是他们需要做.也就是说,如果你投了重新开放的票,我不会大惊小怪。tidyr::filldf1 %>% fill(Text2, .direction = "up") %>% group_by(Group) %>% filter(!(is.na(Text) & sum(!is.na(Text)) > 0))
0赞 Gabriela Zuquim 11/7/2023
事实上,线程并不完全相同,特别是因为我正在处理字符串。但 ThomasIsCoding 找到了答案。谢谢大家!

答:

1赞 PGSA 11/3/2023 #1
library(tidyverse)

test <- data.frame(
  Group = c("A", "A", "B", "B", "C"),
  Text = c("Apple", NA, "Cherry", NA, "Grape"),
  Text2 = c(NA, "Banana", NA, "Cherry", NA)
)
test |> group_by(Group) |> mutate(Text = na.omit(unique(Text)),
                                  Text2 = ifelse(length(na.omit(unique(Text2))) > 0,
                                                 na.omit(unique(Text2)), 
                                                 NA_character_)) |>
  distinct()

给:

# A tibble: 3 × 3
# Groups:   Group [3]
  Group Text   Text2 
  <chr> <chr>  <chr> 
1 A     Apple  Banana
2 B     Cherry Cherry
3 C     Grape  NA   

这通过使用 - 列出所有唯一值并删除 NA 来工作。
由于我们希望在没有有效水果的情况下在 Text2 中保留 NA,因此我们添加一个测试,如果不保留任何值,则放入 NA。
首先对数据框进行分组只是确保我们只在每个组中查找唯一值。
删除不需要的行。
na.omit(unique(...))na.omit(unique(...))distinct()

评论

0赞 Gabriela Zuquim 11/7/2023
谢谢!但是我收到错误消息 Error in : !分配的数据必须与现有数据兼容。✖ 现有数据有 5 行。✖ 分配的数据有 3 行。i 只有大小为 1 的载体被回收。由 : !无法将大小为 3 的输入回收到大小 5。运行以查看错误发生的位置。[[<-valuevectbl_recycle_rhs_rows()rlang::last_trace()
2赞 Maël 11/3/2023 #2

您可以使用检查是否所有值都是 NA;如果是这样,请保留 NA,如果没有,则用于保留唯一的非 NA。用于按组执行此操作:ifelsena.omit.by

library(dplyr)
test |> 
  summarise(across(contains("Text"), ~ ifelse(all(is.na(.x)), NA, na.omit(.x))), 
            .by = Group)

#   Group   Text  Text2
# 1     A  Apple Banana
# 2     B Cherry Cherry
# 3     C  Grape   <NA>

评论

0赞 Gabriela Zuquim 11/7/2023
我收到一条错误消息:错误:!只能在数据屏蔽谓词(如 、 和 )中使用。运行以查看错误发生的位置。across()mutate()filter()group_by()rlang::last_trace()
0赞 Maël 11/7/2023
可能是因为你没有更新,是最近的dplyr.by
0赞 Gabriela Zuquim 11/8/2023
事实上!我更新了它,现在它可以工作了。谢谢。
2赞 GuedesBF 11/3/2023 #3

我会使用 na.last = TRUE,然后用所有 NA 找出行。summarisesortfilter

library(dplyr)

test |> 
    group_by(Group) |> 
    summarise(across(matches("Text\\d*"),
                     \(x) sort(x, na.last = TRUE))) |> 
    filter(!if_all(matches("Text\\d*"), is.na)) |> 
    ungroup()

# A tibble: 3 × 3
  Group Text   Text2 
  <chr> <chr>  <chr> 
1 A     Apple  Banana
2 B     Cherry Cherry
3 C     Grape  NA   

评论

0赞 Gabriela Zuquim 11/7/2023
这给了我以下错误:错误:!只能在数据屏蔽谓词(如 、 和 )中使用。运行以查看错误发生的位置。across()mutate()filter()group_by()rlang::last_trace()
2赞 ThomasIsCoding 11/3/2023 #4

一个技巧aggregate

> aggregate(. ~ Group, test, na.omit, na.action = na.pass)
  Group   Text  Text2
1     A  Apple Banana
2     B Cherry Cherry
3     C  Grape

或者,如果你想保留而不是空字符串,你可以尝试NA""

aggregate(
    . ~ Group,
    test, 
    \(x) ifelse(all(is.na(x)), NA, na.omit(x)),
    na.action = na.pass
)

这给了

  Group   Text  Text2
1     A  Apple Banana
2     B Cherry Cherry
3     C  Grape   <NA>

评论

0赞 Gabriela Zuquim 11/7/2023
太好了,工作顺利!