【问题标题】:Replacing part of a string using a lookup table使用查找表替换部分字符串
【发布时间】:2019-08-06 19:16:18
【问题描述】:

我有两个数据框:

DF1:一列200行的字符串

DF2:两列 130 行:

  • 第一列有一个包含在 DF1$messy 中的子字符串

  • 第二列有另一个具有正确命名的字符串。

看起来像这样

DF1: 
-----------------
|   messy   |

| abc.'123_c |

| def.'456_c |

| hij.'789_c |


DF2:
-----------------
|   old_str      |    new_str    |

|    123         |      aa       |

|    789         |      cc       |

我需要一种方法将字段 DF2$new_str 引入 DF1,方法是将字段 DF1$messy 匹配到子字符串 DF2$old_str

我首先尝试编写一个 for 循环,期望该函数将应用于整个列:

    df1$new.str <- 0
    correct_field <-
     for (i in 1:nrow(df1)){ 
      IF (df1$messy[i] == df2$old_str)
      df1$clean[i] = df2$new_str
    }

第二次尝试difference_left_join函数:

    library(dplyr)
    library(fuzzyjoin)
    test<-difference_left_join(df1, df2, by = c(cut = 'Data.Lake.Field' )

(我将两个集合中的连接列重命名为“Data.Lake.Field”)

期望的输出:

-----------------
|   messy      |    new_str    |

|    abc.'123_c         |      aa       |

|    def.'456_c         |     NULL      |

|    hij.'789_c         |      cc       |

编辑: 我认为,理论上,解决这个问题的最好方法是一个 FOR 循环,在 DF1 中有一个新列,它在 DF1$messy 中占用一行 [i],并在 DF2$old 中搜索匹配项,并用与 DF2$old 值相关的 DF2$new 的确切值。我不知道如何做到这一点,因为对一行使用 [i] 后缀总是返回相同的行号......例如,我将如何取一行 - 比如说 DF1$messy[142] - 并创建与 DF2$old[15] 进行模糊匹配,并创建一个返回 DF2$new[15] 的新列???

【问题讨论】:

  • 我不知道我是否会认为这是fuzzyjoin 的情况,如果匹配项实际上是在原始字符串中表示的(即,您正在匹配字符串的一部分,而不是尝试根据不正确的拼写进行匹配)。
  • 单引号可能会导致问题。您应该使用 dput 来生成 hte 数据对象的明确表示。
  • 我认为,理论上,解决这个问题的最佳方法是一个 FOR 循环,在 DF1 中有一个新列,它在 DF1$messy 中占用一行 [i],并在 DF2 中搜索匹配项$old,并使用与该 DF2$old 值相关的 DF2$new 的确切值填充该字段。我不知道如何做到这一点,因为对一行使用 [i] 后缀总是返回相同的行号......例如,我将如何取一行 - 比如说 DF1$messy[142] - 并创建与 DF2$old[15] 进行模糊匹配,并创建一个返回 DF2$new[15] 的新列???
  • 接着@42 的评论说,如果您包含更多数据和代码会更容易,以便我们更好地了解问题所在。
  • 结束投票理由:“寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定问题或错误以及在问题本身。没有明确问题陈述的问题对其他读者没有用处。”

标签: r for-loop dplyr


【解决方案1】:

您可以折叠搜索词并将它们与原始数据中的“杂乱”词进行匹配。然后使用匹配项加入数据框。

df1 <- data.frame(messy=c('abc','def','ghi'),stringsAsFactors = F)
df2 <- data.frame(old=c('ab','ef','hi'),new=c(1:3),
                  stringsAsFactors = F)

df2$messy <- grep(paste(df2$old,collapse = '|'),df1$messy,value = T)

left_join(df2,df1)

Joining, by = "messy"
  old new messy
1  ab   1   abc
2  ef   2   def
3  hi   3   ghi

【讨论】:

  • 我试过这个,但我得到的错误是:警告消息:列Data.Lake.Field加入不同级别的因子,强制转换为字符向量......看看粘贴函数做了什么,它创建了一个一大堆 noie 和一个非常长的字符串,跨行是相同的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-18
  • 2021-11-15
  • 2023-02-13
  • 1970-01-01
  • 1970-01-01
  • 2015-09-26
  • 2017-01-17
相关资源
最近更新 更多