【问题标题】:Populating NAs and correcting data based on sequence within a sequence根据序列中的序列填充 NA 和更正数据
【发布时间】:2019-10-30 13:32:43
【问题描述】:

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

        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 中分配的内容填写 在其他时候,我可能有 2 个(或更多)相同 ID1 的不同名称,但应该只有一个。在 ID1 中按 ID2 顺序排在第一位的名称应该是所有 ID1 的指定名称

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

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

有什么想法吗?我将它作为数据表使用,因为我通常使用它们,但这不是必需的。

【问题讨论】:

  • 预期的输出不应该是最后的观察结果吗?
  • 不,它是 ID1 中 ID2 序列中最先出现的内容

标签: r data.table na updating


【解决方案1】:

这可能有效:

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

【讨论】:

  • 整洁(我绕道而行),添加tempdt[, name := first(na.omit(name[order(ID2)])), keyby = ID1]data.table 等效!
  • 太棒了! dplyer 和 data.table 解决方案都有效。我试过几张大约 5K 到 10K 长的桌子。谢谢user2474226和JDG。
【解决方案2】:

您可以执行以下操作:

# 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

【讨论】:

    猜你喜欢
    • 2018-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-27
    • 2021-12-18
    • 2021-04-21
    • 2018-05-26
    相关资源
    最近更新 更多