【问题标题】:Replace NAs with the values selected by another column用另一列选择的值替换 NA
【发布时间】:2019-08-23 15:52:51
【问题描述】:

我有一个第一列中缺少值的表。 第一列和第二列之间存在关系,即, 第一列有一个唯一的 NAME,对应于第二列中的许多 ID。

例如:

  • A 有 (ID1, ID2, ID3)
  • B 有 (ID4)
  • C 有 (ID5, ID6)

NAME 列中的 NA 需要替换为其列中的现有值之一(A 或 B 或 C)。选择是通过第二列中的 ID 完成的。 例如,第一个 NA 有 ID3。查表,ID3对应A,所以将NA替换为A。
第三列在这一步没有任何作用,但我在接下来的操作中也需要它。

这是它目前的外观:

NAME |    ID     |    Value
A    |    ID1    |    V1
A    |    ID2    |    V2
A    |    ID3    |    V3
B    |    ID4    |    V4
C    |    ID5    |    V5
C    |    ID6    |    V6
NA   |    ID3    |    V7
NA   |    ID1    |     V8
NA   |   ID5     |    V9
NA   |   ID4     |    V10
NA   |   ID5     |    V11

应该是这样的

Name |    ID     |    Value
A    |    ID1    |    V1
A    |    ID2    |    V2
A    |    ID3    |    V3
B    |    ID4    |    V4
C    |    ID5    |    V5
C    |    ID6    |    V6
A    |    ID3    |    V7
A    |    ID1    |    V8
C    |    ID5    |    V9
B    |    ID4    |    V10
C    |    ID5    |    V11

我在 dplyr 和数据表的不同方法之间陷入困境,无法取得任何进展。 知道如何继续前进吗? 谢谢。

【问题讨论】:

    标签: r


    【解决方案1】:

    这是dplyr 解决方案:

    library(dplyr)
    
    # example data
    dt = read.table(text = "
    NAME     ID         Value
    A        ID1        V1
    A        ID2        V2
    A        ID3        V3
    B        ID4        V4
    C        ID5        V5
    C        ID6        V6
    NA       ID3        V7
    NA       ID1         V8
    NA      ID5         V9
    NA      ID4         V10
    NA      ID5         V11 
    ", header=T, stringsAsFactors=F)
    
    dt %>%
      group_by(ID) %>%                               # for each ID
      mutate(NAME = unique(NAME[!is.na(NAME)])) %>%  # get the non-NA value of NAME
      ungroup()                                      # forget the grouping
    
    
    # # A tibble: 11 x 3
    #   NAME  ID    Value
    #   <chr> <chr> <chr>
    # 1 A     ID1   V1   
    # 2 A     ID2   V2   
    # 3 A     ID3   V3   
    # 4 B     ID4   V4   
    # 5 C     ID5   V5   
    # 6 C     ID6   V6   
    # 7 A     ID3   V7   
    # 8 A     ID1   V8   
    # 9 C     ID5   V9   
    #10 B     ID4   V10  
    #11 C     ID5   V11 
    

    注意: 这也适用于因子变量。 对于您发布的特定示例,您实际上并不需要 unique(.),但这是更一般的情况(即,如果您有多个行用于特定 ID 和非 NA NAME 值)。

    【讨论】:

    • 非常感谢,它完美运行!还有一个问题:如果我将 NAME 和 ID 的行加倍,例如 (A ID1 V20) 并尝试运行代码,我会收到错误:错误:列 NAME 必须是长度 3(组大小)或一,而不是 2。在我使用的表中,我遇到了这种情况,必须使用所有行进行进一步处理。谢谢
    • 这应该不是unique 的问题。我认为这个过程会中断,因为对于特定的ID,您可能会有不同的NAME 值。类似于A ID1 的一行,然后在B ID1 某处的另一行,该过程不知道该选择哪一个。你能检查一下是不是这样吗?
    【解决方案2】:

    首先,您必须以某种方式将数据输入 R。此过程超出了答案的范围。

    temp
    #    NAME  ID Value
    # 1     A ID1    V1
    # 2     A ID2    V2
    # 3     A ID3    V3
    # 4     B ID4    V4
    # 5     C ID5    V5
    # 6     C ID6    V6
    # 7  <NA> ID3    V7
    # 8  <NA> ID1    V8
    # 9  <NA> ID5    V9
    # 10 <NA> ID4   V10
    # 11 <NA> ID5   V11
    

    以下解决方案不使用dplyr,仅使用do.call 的基本R。

    temp2 <- table (temp$NAME, temp$ID)
    temp2
    
    #    ID1 ID2 ID3 ID4 ID5 ID6
    #  A   1   1   1   0   0   0
    #  B   0   0   0   1   0   0
    #  C   0   0   0   0   1   1
    

    您不能直接使用该表。首先,您必须将其转换为数据框。

    temp3 <- as.data.frame.matrix(temp2)
    temp3
    
    #    ID1 ID2 ID3 ID4 ID5 ID6
    # A   1   1   1   0   0   0
    # B   0   0   0   1   0   0
    # C   0   0   0   0   1   1
    

    比如你想把ID5对应的NA换成“C”。

    rownames (temp3[which(temp3$ID5 == 1),])
    # [1] "C"
    

    现在让我们把它放到一个函数中。

    returnName <- function (df, id)
    {
        rowTemp <- do.call ('$', list(df, id))
        name <- rownames (df[which(rowTemp == 1),])
        return (name)
    }
    
    temp$NAME <- sapply (temp$ID, returnName, df = temp3)
    
    temp
    #    NAME  ID Value
    # 1     A ID1    V1
    # 2     A ID2    V2
    # 3     A ID3    V3
    # 4     B ID4    V4
    # 5     C ID5    V5
    # 6     C ID6    V6
    # 7     A ID3    V7
    # 8     A ID1    V8
    # 9     C ID5    V9
    # 10    B ID4   V10
    # 11    C ID5   V11
    

    【讨论】:

    • 谢谢,这在我在本网站上提供的示例中运行良好。但我面临的问题是,事实上,我使用的桌子大约有 700 万。行。不幸的是,它卡住了,最近崩溃了。
    • 看来您应该研究 data.table 并使用它,请参阅《R in Action》一书。
    猜你喜欢
    • 2016-03-08
    • 2022-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-09
    • 2020-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多