根据序列中的序列填充 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
我有一个数据框,其中有两个问题我正在尝试更正。这是一个玩具示例。
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