首页 > 解决方案 > 根据单独的列表/数据框 R 替换字符串

问题描述

我正在尝试做一些我认为很简单但让我难过的事情。

假设我有以下数据框:

id <- c("bob_geldof", "billy_bragg", "melvin_smith")
code <- c("blah", "di", "blink")
df <- as.data.frame(cbind(id,code))

> df
             id  code
1    bob_geldof  blah
2   billy_bragg    di
3  melvin_smith blink

还有一个是这样的:

ID1 <- c("bob_geldof", "melvin_smith")
ID2 <- c("the_builder", "kelvin")
alternates <- as.data.frame(cbind(ID1, ID2))

> alternates
            ID1         ID2
1    bob_geldof the_builder
2  melvin_smith      kelvin

如果 df$id 中的字符串与alternates$ID1 匹配,我想将其替换为alternates$ID2。如果不匹配,我想保持原样。

最终的 df 应该看起来像

> df
               id   code
1 bob_the_builder   blah
2     billy_bragg     di
3   melvin_kelvin  blink

这显然是一个愚蠢的例子,我的真实数据集需要大量替换。

我已经包含了“代码”列,以证明我正在使用数据框而不仅仅是字符向量。

我一直在使用 gsub 单独替换它们,但这很耗时,而且列表不断变化。

我查看了 str_replace 但似乎您只能指定一个替换值。

任何帮助将非常感激。

干杯!

编辑:并非所有 id 都包含下划线,我需要保留匹配的位。例如 bob_geldolf 变成 bob_the_builder。

编辑2(!):感谢大家的建议。我通过合并数据框(以便有不需要进行更改的 NA)并使用 ifelse 语句创建新 ID 来解决问题。这有点笨拙,但它有效!

标签: rreplacecharactertidyversegsub

解决方案


在创建dataframes使用stringsAsFactors = FALSE时不要处理因素。然后,如果行是有序的,只需应用:

df <- as.data.frame(cbind(id,code),stringsAsFactors = FALSE)
alternates <- as.data.frame(cbind(ID1, ID2),stringsAsFactors = FALSE)

df$id[c(TRUE,FALSE)]=paste(gsub("(.*)(_.*)","\\1",df$id[c(TRUE,FALSE)]),
                         alternates$ID2,sep="_")

> df
               id  code
1 bob_the_builder  blah
2     billy_bragg    di
3   melvin_kelvin blink

如果它们是无序的,我们可以使用dlyr

df%>%rowwise()%>%mutate(id=if_else(length(which(alternates$ID1==id))>0,
                                  paste(gsub("(.*)(_.*)","\\1",id),
                                        alternates$ID2[which(alternates$ID1==id)],sep="_"),
                                  id))
# A tibble: 3 x 2
  id              code 
  <chr>           <chr>
1 bob_the_builder blah 
2 billy_bragg     di   
3 melvin_kelvin   blink

我们使用与以前相同的逻辑。在这里,我们df逐行检查。如果它id匹配任何一个alternatives$ID1(由length()),我们更新它。


推荐阅读