这是使用dplyr 实现此目的的一种方法。 filter(!is.na(Initials)) 将删除所有带有 NA 的行。 distinct() 将删除重复的行:
library(dplyr)
Data %>%
filter(!is.na(Initials)) %>%
distinct()
EweID DateSampled Initials
1 1 2021-10-13 AB
2 2 2021-10-27 AB
3 2 2021-10-27 CD
4 3 2021-11-10 AB
5 4 2021-11-24 AB
6 4 2021-11-24 CD
7 5 2021-12-01 AB
更新
感谢您澄清您的输出,这是一种实现方法。首先是为每只动物创建一个中间数据框并计算每组NA 的数量:
Number_of_NA = Data %>%
group_by(AnimalID)%>%
summarise(n = sum(is.na(Initials)))
> Number_of_NA
# A tibble: 7 x 2
AnimalID n
<dbl> <int>
1 1 2
2 2 0
3 3 2
4 4 0
5 5 2
6 6 4
7 7 4
如果我理解正确,您希望与NA 保持一致的组将始终具有 4 个 NA 值。您可以像以前一样使用它来过滤数据框中的所有NA,然后加入只有 4 个 NA 的组:
Data %>% filter(!is.na(Initials)) %>%
full_join(filter(Data, AnimalID %in% Number_of_NA$AnimalID[Number_of_NA$n == 4]))
AnimalID DateSampled Initials
1 1 2021-10-13 AB
2 1 2021-10-13 AB
3 2 2021-10-27 AB
4 2 2021-10-27 AB
5 2 2021-10-27 CD
6 2 2021-10-27 CD
7 3 2021-11-10 AB
8 3 2021-11-10 AB
9 4 2021-11-24 AB
10 4 2021-11-24 AB
11 4 2021-11-24 CD
12 4 2021-11-24 CD
13 5 2021-12-01 AB
14 5 2021-12-01 AB
15 6 2021-12-05 <NA>
16 6 2021-12-05 <NA>
17 6 2021-12-05 <NA>
18 6 2021-12-05 <NA>
19 7 2021-12-15 <NA>
20 7 2021-12-15 <NA>
21 7 2021-12-15 <NA>
22 7 2021-12-15 <NA>
数据
Data = structure(list(AnimalID = c(1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3,
3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7), DateSampled = structure(c(18913,
18913, 18913, 18913, 18927, 18927, 18927, 18927, 18941, 18941,
18941, 18941, 18955, 18955, 18955, 18955, 18962, 18962, 18962,
18962, 18966, 18966, 18966, 18966, 18976, 18976, 18976, 18976
), class = "Date"), Initials = c("AB", "AB", NA, NA, "AB", "AB",
"CD", "CD", "AB", "AB", NA, NA, "AB", "AB", "CD", "CD", "AB",
"AB", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)), row.names = c(NA,
-28L), class = "data.frame")
更新 2
这是与您的过滤匹配的修改。在第一个数据框中我们group_by()动物ID和日期,然后计算NA的数量(with_NA)和观察总数total_n。在这种情况下,如果with_NA 等于total_n,这意味着只有 NA 可用于此 ID 和 Date,因此这些 NA 将被保留。
library(dplyr)
df_filt = Data %>%
group_by(AnimalID, DateSampled)%>%
summarise(with_NA = sum(is.na(Initials)), total_n = n(),
to_filter = with_NA == total_n) %>%
filter(to_filter == TRUE)
# A tibble: 3 x 5
# Groups: AnimalID [3]
AnimalID DateSampled with_NA total_n to_filter
<dbl> <date> <int> <int> <lgl>
1 3 2021-11-11 1 1 TRUE
2 6 2021-12-05 4 4 TRUE
3 7 2021-12-16 2 2 TRUE
然后我们可以使用类似于上次的东西来过滤数据帧中的所有 NA,然后根据上面的数据帧加入我们想要保留的那个:
Data %>% filter(!is.na(Initials)) %>%
full_join(filter(Data, AnimalID %in% df_filt$AnimalID & DateSampled %in% df_filt$DateSampled))%>%
arrange(AnimalID)
AnimalID DateSampled Initials
1 1 2021-10-13 AB
2 1 2021-10-13 AB
3 2 2021-10-27 AB
4 2 2021-10-27 AB
5 2 2021-10-27 CD
6 2 2021-10-27 CD
7 3 2021-11-10 AB
8 3 2021-11-10 AB
9 3 2021-11-11 <NA>
10 4 2021-11-24 AB
11 4 2021-11-24 AB
12 4 2021-11-24 CD
13 4 2021-11-24 CD
14 5 2021-12-01 AB
15 5 2021-12-01 AB
16 6 2021-12-05 <NA>
17 6 2021-12-05 <NA>
18 6 2021-12-05 <NA>
19 6 2021-12-05 <NA>
20 7 2021-12-15 CB
21 7 2021-12-16 <NA>
22 7 2021-12-16 <NA>
在这种情况下,所有具有匹配 Date 和 AnimalID 与 Initial 的 NA 将被丢弃,并且仅保留该日期没有实际 Initial 的 NA。
请注意,我在这里稍微修改了数据以反映所需的输出
数据 2
> Data
AnimalID DateSampled Initials
1 1 2021-10-13 AB
2 1 2021-10-13 AB
3 1 2021-10-13 <NA>
4 1 2021-10-13 <NA>
5 2 2021-10-27 AB
6 2 2021-10-27 AB
7 2 2021-10-27 CD
8 2 2021-10-27 CD
9 3 2021-11-10 AB
10 3 2021-11-10 AB
11 3 2021-11-10 <NA>
12 3 2021-11-11 <NA>
13 4 2021-11-24 AB
14 4 2021-11-24 AB
15 4 2021-11-24 CD
16 4 2021-11-24 CD
17 5 2021-12-01 AB
18 5 2021-12-01 AB
19 5 2021-12-01 <NA>
20 5 2021-12-01 <NA>
21 6 2021-12-05 <NA>
22 6 2021-12-05 <NA>
23 6 2021-12-05 <NA>
24 6 2021-12-05 <NA>
25 7 2021-12-15 CB
26 7 2021-12-15 <NA>
27 7 2021-12-16 <NA>
28 7 2021-12-16 <NA>
Data = structure(list(AnimalID = c(1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3,
3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7), DateSampled = structure(c(18913,
18913, 18913, 18913, 18927, 18927, 18927, 18927, 18941, 18941,
18941, 18942, 18955, 18955, 18955, 18955, 18962, 18962, 18962,
18962, 18966, 18966, 18966, 18966, 18976, 18976, 18977, 18977
), class = "Date"), Initials = c("AB", "AB", NA, NA, "AB", "AB",
"CD", "CD", "AB", "AB", NA, NA, "AB", "AB", "CD", "CD", "AB",
"AB", NA, NA, NA, NA, NA, NA, "CB", NA, NA, NA)), row.names = c(NA,
-28L), class = "data.frame")