【问题标题】:How can I replace several values in a data frame from another one if they are repeated more than once如果重复多次,如何从另一个数据框中替换数据框中的多个值
【发布时间】:2021-10-24 02:38:42
【问题描述】:

我有一个 A 矩阵的数据框,如下所示:

  V1 V2 V3
1  1  1  1
2  2  1  0
3  2  2  1
4  3  1  0
5  3  2  0
6  3  3  1

我还有一个交叉引用数据框,其中包含原始的 ID 和新的 ID,如下所示:

  ID newID
1 SE1     1
2  T3     2
3  R5     3
4  R7     4
5  R9     5
6 A11     6

如何使用获取这样的数据框(在创建新列ID1ID2 之后)?

  V1 V2 V3 ID1 ID2
1  1  1  1 SE1 SE1
2  2  1  0 T3  SE1
3  2  2  1 T3  T3
4  3  1  0 R5  SE1
5  3  2  0 R5  T3
6  3  3  1 R5  R5

【问题讨论】:

    标签: r dataframe for-loop replace merge


    【解决方案1】:

    我们可以使用inner_join 两次:

    library(dplyr)
    
    df %>% 
        inner_join(df1, by=c("V1"="newID")) %>% 
        inner_join(df1, by=c("V2"="newID")) %>% 
        rename(ID1 = ID.x, ID2 = ID.y)
    
    
      V1 V2 V3 ID1 ID2
    1  1  1  1 SE1 SE1
    2  2  1  0  T3 SE1
    3  2  2  1  T3  T3
    4  3  1  0  R5 SE1
    5  3  2  0  R5  T3
    6  3  3  1  R5  R5
    

    【讨论】:

      【解决方案2】:

      您可以解构您的参考数据。框架创建一个查找表:

      ref <- tibble::deframe(ref[c("newID", "ID")])
      #>     1     2     3     4     5     6 
      #> "SE1"  "T3"  "R5"  "R7"  "R9" "A11" 
      

      现在你可以使用mutate:

      library(dplyr)
      
      data %>% 
        mutate(ID1 = ref[V1],
               ID2 = ref[V2])
      

      得到

      # A tibble: 6 x 5
           V1    V2    V3 ID1   ID2  
        <dbl> <dbl> <dbl> <chr> <chr>
      1     1     1     1 SE1   SE1  
      2     2     1     0 T3    SE1  
      3     2     2     1 T3    T3   
      4     3     1     0 R5    SE1  
      5     3     2     0 R5    T3   
      6     3     3     1 R5    R5
      

      【讨论】:

      • 你可以做data %&gt;% mutate(across(V1:V2, ~ ref[.], .names = "{str_replace(.col, 'V', 'ID')}"))
      • 啊!非常感谢!我尝试了类似的方法,但我只将.col 包裹在{ } 中。
      【解决方案3】:

      base R 中的一个选项是创建一个命名向量并用于匹配和替换

      v1 <- with(df2, setNames(ID, newID))
      df1[paste0("ID", 1:2)] <- lapply(df1[-3], function(x) v1[as.character(x)])
      

      -输出

      > df1
        V1 V2 V3 ID1 ID2
      1  1  1  1 SE1 SE1
      2  2  1  0  T3 SE1
      3  2  2  1  T3  T3
      4  3  1  0  R5 SE1
      5  3  2  0  R5  T3
      6  3  3  1  R5  R5
      

      数据

      df1 <- structure(list(V1 = c(1L, 2L, 2L, 3L, 3L, 3L), V2 = c(1L, 1L, 
      2L, 1L, 2L, 3L), V3 = c(1L, 0L, 1L, 0L, 0L, 1L)), class = "data.frame", 
      row.names = c("1", 
      "2", "3", "4", "5", "6"))
      
      df2 <- structure(list(ID = c("SE1", "T3", "R5", "R7", "R9", "A11"), 
          newID = 1:6), class = "data.frame", row.names = c("1", "2", 
      "3", "4", "5", "6"))
      

      【讨论】:

      • 有点题外话:有没有mutate(across(...)) 的方式来创建名为ID1ID2 的新列?我想不通,创建ID_V1ID_V2 之类的东西很容易,但我不能放弃V
      • @MartinGal 我在您的帖子下方发表了评论。
      猜你喜欢
      • 2022-10-05
      • 2019-05-09
      • 1970-01-01
      • 2022-01-23
      • 2012-06-26
      • 2020-09-28
      • 2021-02-18
      • 2020-10-10
      • 1970-01-01
      相关资源
      最近更新 更多