首页 > 解决方案 > 使用数据框中的不同值替换字符串的某些相等元素

问题描述

我想用“a”列中的每个元素替换“测试”数据框的“b”列中的每个“COL”单词,并将结果放在其他列中,但同时保留字符的顺序和结构'b' 列的字符串。

test <- data.frame(a = c("COL167", "COL2010;COL2012"),
                   b = c("COL;MO, K", "P;COL, NY, S, COL"))

我尝试了以下方法,但这不是我需要的结果:

for(i in 1:length(test$a)){
    test$c[i] <- gsub(pattern = "COL", x = test$b[i], replacement = test$a[i])
}

> test
                a                  b                                          c
1          COL167          COL;MO, K                               COL167;MO, K
2 COL2010;COL2012  P;COL, NY, S, COL  P;COL2010;COL2012, NY, S, COL2010;COL2012

我期待以下结果:

              a                  b                          c
1          COL167          COL;MO, K               COL167;MO, K
2 COL2010;COL2012  P;COL, NY, S, COL  P;COL2010, NY, S, COL2012

标签: rdataframegsub

解决方案


在您已经完成的工作的基础上,我认为这会起作用,但请注意,如果您的表很大,您可能会看到一些性能问题。另请注意,这假定要替换的值的大小等于用于替换的值。

由于gsub不允许向量化替换(用替换的第一个值替换所有匹配的实例),这里我已将字符串和替换都转换为向量,因此我可以单独替换每个匹配的子字符串。

test <- data.frame(a = c("COL167", "COL2010;COL2012"),
                   b = c("COL;MO, K", "P;COL, NY, S, COL"))

re = function(string, replacement){
  gsub('COL', replacement, string)
}

for(i in 1:nrow(test)){
  #splitting values of column a into vector, this is required for replacement
  replacement = unlist(strsplit(test$a[i], ';'))
  
  #split values of column b into vecto, this is required for replacement
  b_value = unlist(strsplit(test$b[i], ' '))
  
  #select those which have 'COL' substring
  ind_to_replace = which(grepl('COL', b_value))
  
  #replace matched values
  result = mapply(re, b_value[ind_to_replace], replacement)
  
  #replace the column b value with new string
  b_value[ind_to_replace] = result
  
  #join the string
  test$results[i] = paste(b_value, collapse = ' ')
}

test
#>                 a                 b                   results
#> 1          COL167         COL;MO, K              COL167;MO, K
#> 2 COL2010;COL2012 P;COL, NY, S, COL P;COL2010, NY, S, COL2012

reprex 包(v0.3.0)于 2020 年 9 月 5 日创建


推荐阅读