【问题标题】:Replacing parts of value (starts_with) in dataframe with values from a different dataframe in R用R中不同数据帧的值替换数据帧中的部分值(starts_with)
【发布时间】:2020-05-09 17:05:52
【问题描述】:

我想将 df1 中的部分值替换为 df2 中的值。如果 df1$col1 以 df2$col1 中的数字开头,则将这四个数字(保持静止)替换为 df2$col2。同样适用于 df1$col2。示例:对于 16122567 替换为 5059,结果为 50592567。尝试过不同类型的starts_with、循环、for(i in ..)、mutate 等。有人吗? (我是 R 新手)。

df1 col1 col2 1 16122567 89992567 2 17236945 16126548 3 95781657 19995670 4 16126972 56972541 df2 col1 col2 1 1612 5059 2 1723 5044 3 8999 5094 4 1999 9053

【问题讨论】:

    标签: r dataframe replace dplyr


    【解决方案1】:

    这是dplyr 的一种方式。我们可以用col1的前4个字符创建一个新列,left_joindf2replaceNA的前4个字符col2.x。最后,我们使用substr 替换特定位置的值。

    library(dplyr)
    
    df3 <- df1 %>%
             mutate(col1 = substr(col1, 1, 4)) %>%
             left_join(df2 %>% mutate(col1 =  as.character(col1)), by = 'col1') %>%
             mutate(col2.y = ifelse(is.na(col2.y), substr(col2.x, 1, 4), col2.y), 
             col2.x = as.character(col2.x))
    
    substr(df3$col2.x, 1, 4) <- df3$col2.y
    
    df3
    #  col1   col2.x col2.y
    #1 1612 50592567   5059
    #2 1723 50446548   5044
    #3 9578 19995670   1999
    #4 1612 50592541   5059
    

    【讨论】:

    • 谢谢。我学到了很多东西,但是在 substr 只愿意接受字符而不是数字方面遇到了一些困难。
    【解决方案2】:

    这是使用基础 R 的另一种方法。我们可以创建一个函数来执行检查和操作文本,然后将该函数应用于我们想要修改的任何列。

    # the data
    df1 <- data.frame(col1 = c(16122567, 17236945, 95781657, 16126972),
                      col2 = c(89992567, 16126548, 19995670, 56972541))
    
    df2 <- data.frame(col1 = c(1612, 1723, 8999, 1999), 
                      col2 = c(5059, 5044, 5094, 9053))   
    
    # a function to do the check and create the chimera strings
    check_and_paste <- function(check1, check2, replacement) {
      res <- c()
      for (i in seq_along(check1)) {
        four_digits <- substr(check1[i], 1, 4)
        if (four_digits %in% check2) {
          res[i] <- paste(replacement[which(four_digits == check2)], 
                          substr(check1[i], 5, 8), 
                          sep = "")
        } else {
          res[i] <- check1[i]
        }
      }
      return(as.numeric(as.character(res))) # to return numbers
    }
    
    # apply to the first column
    new_col1 <- check_and_paste(
      check1 = df1$col1,
      check2 = df2$col1,
      replacement = df2$col2
    )
    
    # and the second
    new_col2 <- check_and_paste(
      check1 = df1$col2,
      check2 = df2$col1,
      replacement = df2$col2
    )
    
    # the new data frame
    data.frame(new_col1, new_col2)
    #  new_col1 new_col2
    #1 50592567 50942567
    #2 50446945 50596548
    #3 95781657 90535670
    #4 50596972 56972541
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-27
      • 2020-05-26
      • 1970-01-01
      • 1970-01-01
      • 2016-07-24
      • 2015-12-19
      • 1970-01-01
      相关资源
      最近更新 更多