Можно попробовать это:
df1 = data.frame(id = rep(c("a", "b","c"), each = 4),
val = c(NA, NA, NA, NA, 1, 2, 2, 3,NA,2,NA,3))
df1
# id val
#1 a NA
#2 a NA
#3 a NA
#4 a NA
#5 b 1
#6 b 2
#7 b 2
#8 b 3
#9 c NA
#10 c 2
#11 c NA
#12 c 3
Задача состоит в том, чтобы удалить все строки, соответствующие любому id
IFF val
для соответствующих id
всех NA
с, и добавить новую строку с этими id
и val = 0
.
В этом примере id = a
.
Примечание: val
для c
также имеет NA
с, но все val
, соответствующие c
, не NA
, поэтому нам нужно удалить соответствующую строку для c
, где val = NA
,
Итак, давайте создадим еще один столбец, скажем, val2
, который указывает, что 0
означает все NA
s и 1 в противном случае.
library(dplyr)
df1 = df1 %>%
group_by(id) %>%
mutate(val2 = if_else(condition = all(is.na(val)),true = 0, false = 1))
df1
# A tibble: 12 x 3
# Groups: id [3]
# id val val2
# <fct> <dbl> <dbl>
#1 a NA 0
#2 a NA 0
#3 a NA 0
#4 a NA 0
#5 b 1 1
#6 b 2 1
#7 b 2 1
#8 b 3 1
#9 c NA 1
#10 c 2 1
#11 c NA 1
#12 c 3 1
Получить список id
с соответствующими val = NA
для всех.
all_na = unique(df1$id[df1$val2 == 0])
Затем удалите id
s из кадра данных df1
с помощью val = NA
.
df1 = na.omit(df1)
df1
# A tibble: 6 x 3
# Groups: id [2]
# id val val2
# <fct> <dbl> <dbl>
# 1 b 1 1
# 2 b 2 1
# 3 b 2 1
# 4 b 3 1
# 5 c 2 1
# 6 c 3 1
И создайте новый фрейм данных с id
s в all_na
и val = 0
all_na_df = data.frame(id = all_na, val = 0)
all_na_df
# id val
# 1 a 0
затем объедините эти два кадра данных.
df1 = bind_rows(all_na_df, df1[,c('id', 'val')])
df1
# id val
# 1 a 0
# 2 b 1
# 3 b 2
# 4 b 2
# 5 b 3
# 6 c 2
# 7 c 3
Надеюсь, это поможет, а правки приветствуются: -)