在两列中搜索和替换数据框中的条目

时间:2016-08-27 21:04:44

标签: r dataframe

我有一个数据集,其中缺少值很少。 数据集如下所示:

a b  c0 d0 c1 d1 g   h
1 5  20 10 NA NA 2   NA
1 6  NA NA 8  2  NA  4 
2 5  25 10 NA NA 2.5 NA
2 7  NA NA 2  2  NA  1
2 8  50 10 NA NA 5   NA
3 9  10 10 NA NA 1   NA
3 6  NA NA 8  4  NA  2  
3 10  NA NA 5  1  NA  5
4 5  NA NA 6  2  NA  3
4 11 25 10 NA NA 2.5 NA

我的数据采用上述格式。列a是一种顺序的时间段,具有与之对应的多个代码。 列b只显示一个项目。此项目具有重复的时间输入或具有唯一值。 列gh只是通过划分列c0 / d0 = gc1 / d1 =而创建的列h。在这里,专栏g更重要。

现在,因为很明显NA很少,而且一些列b条目是重复的,而休息是唯一的。

我必须执行以下步骤才能计算列中的NA'

  1. 我必须在'列中找到b'这是重复的条目或具有唯一的值.Eg:条目6和5重复,而7,8 9,10和11是唯一的。

  2. 一旦找到,下一步是确定g'列中是否有值。已经用于该项目。

  3. 如果有,那么我们需要在'列g'中取平均重复值。如果它不是NA,就像项目5一样,我可以发现值为2和2.5,因此2.25的平均值应放在'列g'对于a = 4处的重复5值。

  4. 现在,如果有一个重复的值但仍然列g是NA,那么我可以简单地选择'列h'值为'列g'。

  5. 对于非重复项目,如9,10,7等,因为它们是唯一的,只需将列g条目替换为h列。

  6. 最终输出应如下:

    a b  c0 d0 c1 d1 g   h
    1 5  20 10 NA NA 2   NA
    1 6  NA NA 8  2  4   4 
    2 5  25 10 NA NA 2.5 NA
    2 7  NA NA 2  2  1   1
    2 8  50 10 NA NA 5   NA
    3 9  10 10 NA NA 1   NA
    3 6  NA NA 8  4  2   2  
    3 10 NA NA 5  1  5   5
    4 5  NA NA 6  2  2.25 3
    4 11 25 10 NA NA 2.5 NA
    

    请你帮我解决。如果您对此问题有任何疑问,请告诉我,或者是否需要更多细节。

2 个答案:

答案 0 :(得分:3)

您想要的输出不一致。您丢失了一行,列h已被更改,因此第七行的列g看起来也不一致。

无论如何,按照你的描述,我会分两步完成。

  1. 您的数据的第一个子集仅由具有欺骗性的b个实例和以该组其余部分的平均值替换NA的实例
  2. NA
  3. 列替换为h左侧的所有内容

    我建议data.table因为它允许对子集进行舒适的操作

    library(data.table)
    setDT(df)[duplicated(b) | duplicated(b, fromLast = TRUE), # operate only on the dupes
              g := replace(g, is.na(g), mean(g, na.rm = TRUE)), by = b] # replace NA by group
    df[is.na(g), g := as.double(h)] # subset by NAs and replace with corresponding values in h
    df
    #     a  b c0 d0 c1 d1    g  h
    #  1: 1  5 20 10 NA NA 2.00 NA
    #  2: 1  6 NA NA  8  2 4.00  4
    #  3: 2  5 25 10 NA NA 2.50 NA
    #  4: 2  7 NA NA  2  2 1.00  1
    #  5: 2  8 50 10 NA NA 5.00 NA
    #  6: 3  9 10 10 NA NA 1.00 NA
    #  7: 3  6 NA NA  8  2 4.00  4
    #  8: 3 10 NA NA  5  1 5.00  5
    #  9: 4  5 NA NA  6  2 2.25  3
    # 10: 4 11 25 10 NA NA 2.50 NA
    

答案 1 :(得分:2)

我们可以将它减少到"一个"一旦我们认识到按b分组时,重复意味着有多个行被分组。因此,将NA中的g值替换为其组的平均值(不是NA)的条件是:

  

b分组的行数大于一个并非组g中的NA <{1}}

否则,请将NA中的g值替换为h

library(data.table)
setDT(df)[, g := if (.N > 1 & !all(is.na(g))) {
                   replace(g, is.na(g), mean(g, na.rm = TRUE)) 
                 } else {
                   replace(g, is.na(g), as.double(h)) 
                 }, by=b][]
##    a  b c0 d0 c1 d1    g  h
## 1: 1  5 20 10 NA NA 2.00 NA
## 2: 1  6 NA NA  8  2 4.00  4
## 3: 2  5 25 10 NA NA 2.50 NA
## 4: 2  7 NA NA  2  2 1.00  1
## 5: 2  8 50 10 NA NA 5.00 NA
## 6: 3  9 10 10 NA NA 1.00 NA
## 7: 3  6 NA NA  8  2 4.00  4
## 8: 3 10 NA NA  5  1 5.00  5
## 9: 4  5 NA NA  6  2 2.25  3
##10: 4 11 25 10 NA NA 2.50 NA