Here is a way to achieve this using dplyr. filter(!is.na(Initials)) wil remove all the rows with NA. distinct() will get rid of the duplicated rows:
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
Update
Thanks for clarifying your output, here is a way to achieve. First is to create a intermediate data frame for each animal and counting the number of NA per group:
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
If I understand correctly the group you want to keep with NA will always have 4 values with NA. You can use this to filter all the NA in the data frame as previously and then join the group with only the 4 NAs:
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
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")
Update 2
Here are the modification to match your filtering. In the first data frame we group_by() animal ID and date, then calculate the number of NA (with_NA) and the number total of observation total_n. In that case if with_NA is equal to total_n, that means only NA are available for this ID and Date therefore these NA will be kept.
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
Then we can use something similar to last time to filter all NA in the dataframe and then join with the one we want to kept based on the dataframe above:
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>
In this case all the NA that have a matching Date and AnimalID with Initial will be discarded and only the NA without real Initial for this date will be kept.
Note that I modified slightly the Data here to reflect on the desired output
Data 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")