通过数据框中的数字有效地填充 NA 单元格

时间:2021-02-13 11:58:57

标签: r dplyr

大家好,我有一个数据框,例如:

     COL1      COL2 COL3
1    G1     SP1_1    1
2    G1     SP1_2    2
3    G1     SP1_3   NA
4    G1  SP43IUGD   NA
5    G1        DG    3
6    G2     SP1_4    1
7    G2     SP1_4    1
8    G2     SP2_3   NA
9    G2     SP2_3   NA
10   G3     SP1_2    1
11   G4     SP2_3   NA
12   G4     SP8_3   NA
13   G4 Species_3   NA
14   G5     SP9_2   NA
15   G5     SP9_2   NA
16   G5      SP10   NA
17   G6       SP6    1
18   G6       SP6    1
19   G6     SP6_1    1
20   G6     SP6_3    2

并且我需要创建一个新的 COL4,在其中我用组中的下一个 df$COL1 值填充 ach highest COL3 中的 NA,如果只有 NA,那么我放 1,然后我继续为其他人使用 number+1 ...... COL2 SP 中所有相同的 COL1 groups 都应该具有相同的 COL3 value。 当根本没有 NA 时,我就坚持价值观。

  • 例如,让我们以 G1 为例:

2 NAs 最大的 COL3 数是 3,然后我将 4 置于 SP1_3 并将 5 置于 SP43IUGD

  • 让我们来看看G5

所有值都是 NAs 然后

两个SP9_2得到1SP10得到2

预期输出

   COL1      COL2 COL3 COL4
1    G1     SP1_1    1    1
2    G1     SP1_2    2    2
3    G1     SP1_3   NA    4
4    G1  SP43IUGD   NA    5
5    G1        DG    3    3
6    G2     SP1_4    1    1
7    G2     SP1_4    1    1
8    G2     SP2_3   NA    2
9    G2     SP2_3   NA    2
10   G3     SP1_2    1    1
11   G4     SP2_3   NA    1
12   G4     SP8_3   NA    2
13   G4 Species_3   NA    3
14   G5     SP9_2   NA    1
15   G5     SP9_2   NA    1
16   G5     SP10    NA    2
17   G6       SP6    1    1
18   G6       SP6    1    1
19   G6     SP6_1    1    1
20   G6     SP6_3    2    2

到目前为止,我尝试了这段代码,但它在巨大的数据帧上非常长,而且并没有真正按预期工作......

df$COL4<-'NA'
row=1
list_groups<-unique(df$COL1)
for(i in list_groups) {
  sub_df<-df[which(df$COL1 ==i) , ]
  list_queries<-unique(sub_df$COL2)
  max_value<-ifelse(all(is.na(sub_df$COL3)), 1, max(sub_df$COL3,na.rm=T))
  for(a in list_queries) {
    sub_sub_df<-sub_df[which(sub_df$COL2 ==a) , ]
    row_num<-as.numeric(rownames(sub_sub_df))
    for(z in row_num){
    df[z,4] <- as.numeric(ifelse(is.na(sub_sub_df$COL3), max_value+1, sub_sub_df$COL3)[1])
    }
  }
}

这是数据

structure(list(COL1 = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 3L, 4L, 4L, 4L, 5L, 5L, 5L, 6L, 6L, 6L, 6L), .Label = c("G1", 
"G2", "G3", "G4", "G5", "G6"), class = "factor"), COL2 = structure(c(2L, 
3L, 4L, 8L, 1L, 5L, 5L, 7L, 7L, 3L, 7L, 12L, 14L, 13L, 13L, 6L, 
9L, 9L, 10L, 11L), .Label = c("DG", "SP1_1", "SP1_2", "SP1_3", 
"SP1_4", "SP10", "SP2_3", "SP43IUGD", "SP6", "SP6_1", "SP6_3", 
"SP8_3", "SP9_2", "Species_3"), class = "factor"), COL3 = c(1L, 
2L, NA, NA, 3L, 1L, 1L, NA, NA, 1L, NA, NA, NA, NA, NA, NA, 1L, 
1L, 1L, 2L)), class = "data.frame", row.names = c(NA, -20L))

2 个答案:

答案 0 :(得分:3)

arrange 数据,所以 NA 总是在每个组中的最后,并使用 match + unique 在每个组中创建一个顺序值。

library(dplyr)

df %>%
  arrange(COL1, COL3) %>%
  group_by(COL1) %>%
  mutate(COL4 = match(COL2, unique(COL2)), 
         COL4 = coalesce(COL3, COL4))

#   COL1  COL2       COL3  COL4
#   <fct> <fct>     <int> <int>
# 1 G1    SP1_1         1     1
# 2 G1    SP1_2         2     2
# 3 G1    DG            3     3
# 4 G1    SP1_3        NA     4
# 5 G1    SP43IUGD     NA     5
# 6 G2    SP1_4         1     1
# 7 G2    SP1_4         1     1
# 8 G2    SP2_3        NA     2
# 9 G2    SP2_3        NA     2
#10 G3    SP1_2         1     1
#11 G4    SP2_3        NA     1
#12 G4    SP8_3        NA     2
#13 G4    Species_3    NA     3
#14 G5    SP9_2        NA     1
#15 G5    SP9_2        NA     1
#16 G5    SP10         NA     2
#17 G6    SP6           1     1
#18 G6    SP6           1     1
#19 G6    SP6_1         1     1
#20 G6    SP6_3         2     2

答案 1 :(得分:0)

我们可以使用factor

library(dplyr)
df %>%
  arrange(COL1, COL3) %>%
  group_by(COL1) %>%
  mutate(COL4 = as.integer(factor(COL2, levels = unique(COL2))))