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

问题描述 投票:0回答:2

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

        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中的ID1为主要序列,ID2为辅助序列)和名称分配。有时名称会丢失,我需要根据该ID1中分配的名称填写该名称有时我可能为同一ID1使用2个(或更多)不同的名称,但应该只有一个。以ID1中ID2的顺序为先的哪个名称应是所有该ID1的分配名称。

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

我可以通过基于两个连续变量对数据帧(表)进行排序,然后对ID1进行for循环并进行更正,来解决这个问题,但似乎应该有一种更清洁,更有效的方法沿着ID1进行排序,并比较ID1中ID2的序列,并进行校正以避免循环。

有什么想法吗?我有它作为数据表,因为我通常与他们一起工作,但这不是必须的。

威尔

r data.table na updating
2个回答
0
投票

您可以执行以下操作:

# 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,对吗?

[您是否还要考虑违反您的“ ID1 / 2中的名字”顺序的非NA name条目?在这种情况下,您只能在上述操作的末尾添加tempdt[, name := first(name), keyby = ID1],因为这会将name[12]强制为joe


0
投票

这可能有效:

tempdt %>% 
  group_by(ID1) %>% 
  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
© www.soinside.com 2019 - 2024. All rights reserved.