根据序列中的序列填充 NA 和校正数据

Populating NAs and correcting data based on sequence within a sequence

我有一个数据框,其中有两个问题我正在尝试更正。这是一个玩具示例。

        require(data.table)
        tempdt <- data.table(ID1=rep(1:6,each=2),ID2=rep(letters[1:2],6),name=c('john','john',NA,'mike','steve',NA,'bob',NA,NA,'henry','joe','frank'))

            ID1 ID2  name
         1:   1   a  john
         2:   1   b  john
         3:   2   a  <NA>
         4:   2   b  mike
         5:   3   a steve
         6:   3   b  <NA>
         7:   4   a   bob
         8:   4   b  <NA>
         9:   5   a  <NA>
        10:   5   b henry
        11:   6   a   joe
        12:   6   b frank

有2个顺序分组变量(ID1作为主序列,ID2作为ID1中的二级序列)和一个名称分配。有时名字会丢失,我需要根据 ID1 中分配的内容来填写 有时我可能对同一个 ID1 有 2 个(或更多)不同的名称,但应该只有一个。 ID1 中 ID2 顺序中最先出现的名称应该是所有 ID1 的指定名称

最终名称字段应显示为 c('john','john','mike','mike','steve','steve','bob','bob','henry','henry','joe','joe')

我可以通过基于两个顺序变量对数据框 (table) 进行排序然后在 ID1 上执行 for 循环并进行更正来解决这个问题,但似乎应该有一个更清洁更有效的方法方法 沿ID1排序,比较ID1中ID2的顺序,进行修正避免循环

有什么想法吗?我把它作为数据 table 因为我经常和他们一起工作,但这不是必需的。

您可以执行以下操作:

# Make a "Dictionary" of primary names per ID1 group
dict = tempdt[ , .(Name = first(name[!is.na(name)])), keyby = ID1] 

# Which ID1s correspond to NA names?
ID1_NA = tempdt[is.na(name), ID1]

# Draw correct names from the Dictionary
tempdt[is.na(name), name := dict[ID1_NA, Name]] 

结果

> tempdt
    ID1 ID2  name
 1:   1   a  john
 2:   1   b  john
 3:   2   a  mike
 4:   2   b  mike
 5:   3   a steve
 6:   3   b steve
 7:   4   a   bob
 8:   4   b   bob
 9:   5   a henry
10:   5   b henry
11:   6   a   joe
12:   6   b frank

我同意 sindri_baldur 关于 name[12] 存在一些混淆的观点。按照你的逻辑,应该是joe吧?

您是否也想考虑违反您的 "first name in ID1/2" 序列的非 NA name 条目?如果是这种情况,您只需将 tempdt[, name := first(name), keyby = ID1] 添加到上述操作的末尾,因为这会将 name[12] 强制为 joe.

这可能有效:

tempdt %>% 
  group_by(ID1) %>% 
  arrange(ID1, ID2)
  mutate(name = first(na.omit(name)))

# A tibble: 12 x 3
# Groups:   ID1 [6]
     ID1 ID2   name 
   <int> <fct> <fct>
 1     1 a     john 
 2     1 b     john 
 3     2 a     mike 
 4     2 b     mike 
 5     3 a     steve
 6     3 b     steve
 7     4 a     bob  
 8     4 b     bob  
 9     5 a     henry
10     5 b     henry
11     6 a     joe  
12     6 b     joe