我有一个数据框架,其中有两个问题我正在尝试纠正。这是一个玩具示例。
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的序列,并进行校正以避免循环。
有什么想法吗?我有它作为数据表,因为我通常与他们一起工作,但这不是必须的。
威尔
您可以执行以下操作:
# 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
。
这可能有效:
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