Замена NA только нулями в непустых группах - PullRequest
0 голосов
/ 21 января 2020

У меня есть проблема, которую легко решить, но я просто не могу ее решить. У меня есть огромный набор данных с группами и переменной. Некоторые группы для этой переменной пусты (заполнены только NA), а некоторые содержат значения, но также и NA.

Например:

ID <- c("A1","A1","A1","A1","B1","B1","B1","B1", "B1", "C1", "C1", "C1")
Value1 <- c(0,2,1,1,NA,1,1,NA,1,NA,NA,NA)
data <- data.frame(ID, Value1)

Я хотел бы изменить все NA на нули, но только в группах, которые иначе содержат информацию.

Так вот так:

ID <- c("A1","A1","A1","A1","B1","B1","B1","B1","B1","C1","C1","C1")
Value1 <- c(0,2,1,1,0,1,1,0,1,NA,NA,NA)

Я пытался использовать group_by (ID) и "replace" с условием max (Value1)> = 0, но либо max () не работает как условие или не работает с NA. К сожалению, в моей работе мне часто понадобились бы такие условия, поэтому я также буду признателен за любые предложения о том, какие пакеты лучше всего подходят для группового выбора.

Ответы [ 4 ]

2 голосов
/ 21 января 2020

Вы можете использовать простое выражение if`, то есть

library(dplyr)
library(tidyr)

data %>% 
 group_by(ID) %>% 
 mutate(Value1 = if (all(is.na(Value1))){Value1}else{replace_na(Value1, 0)})

, которое дает,

# A tibble: 12 x 2
# Groups:   ID [3]
   ID    Value1
   <fct>  <dbl>
 1 A1         0
 2 A1         2
 3 A1         1
 4 A1         1
 5 B1         0
 6 B1         1
 7 B1         1
 8 B1         0
 9 B1         1
10 C1        NA
11 C1        NA
12 C1        NA
0 голосов
/ 21 января 2020

Использование data.table

setDT(data)
data[, Value1 := if (all(is.na(Value1))) NA else replace(Value1, is.na(Value1), 0), by = ID]

    ID Value1
 1: A1      0
 2: A1      2
 3: A1      1
 4: A1      1
 5: B1      0
 6: B1      1
 7: B1      1
 8: B1      0
 9: B1      1
10: C1     NA
11: C1     NA
12: C1     NA
0 голосов
/ 21 января 2020

С dplyr:

data %>%
  group_by(ID) %>%
  mutate(Value1 = ifelse(any(!is.na(Value1)) & is.na(Value1), 0, Value1))

# A tibble: 12 x 2
# Groups:   ID [3]
   ID    Value1
   <fct>  <dbl>
 1 A1         0
 2 A1         2
 3 A1         1
 4 A1         1
 5 B1         0
 6 B1         1
 7 B1         1
 8 B1         0
 9 B1         1
10 C1        NA
11 C1        NA
12 C1        NA
0 голосов
/ 21 января 2020

Вот базовое решение R

dfout <- Reduce(rbind,
                lapply(split(data,data$ID),
                       function(v) {if (!all(is.na(v$Value1))) v$Value1[is.na(v$Value1)]<- 0; v}))

такое, что

> dfout
   ID Value1
1  A1      0
2  A1      2
3  A1      1
4  A1      1
5  B1      0
6  B1      1
7  B1      1
8  B1      0
9  B1      1
10 C1     NA
11 C1     NA
12 C1     NA
...