在R中查找一个字符串是否包含在另一个字符串中

3

我将尝试在另一个数据框中查找一个字符串是否包含在另一个字符串中。我正在使用if语句和for循环,并且希望保持现有结构,但是无法找到正确的语法使用。 我的第一个数据框的示例为:

Route1
x y z
w x f z 
a b c
x y z

我的第二个数据框的示例是:

Route2      Track
x y z        A
v w x f z    B
a b          C

一旦我确定Route1是否包含在Route2中,我想要为Route1分配相应的Track。因此,数据框DataFrame1的最终结果应该是:
Route1   CalculatedTrack
x y z     A
w x f z   B
a b
x y z     A

我目前拥有的公式是:
for (i in 1:nrow(df1)){
  for (j in 1:nrow(df2)){
    if((((grepl(df1$Route1[i], df2$Route2[j],perl = TRUE)==TRUE){
      df1$CalculatedTrack<-df2$Track[j]
    }
  }
}

因此,我希望能够遍历每一行,看看Route1是否在任何一个Route2中。请注意,每个数据框中都有多个列。
感谢您的任何帮助。

如果速度是一个问题,可以查看基本R或data.table包中的?merge - Manuel Bickel
合并时,“路由”不需要完全相同吗? - Fiona
你是对的,抱歉,我忽略了你也在寻找部分匹配。那么你可能需要使用%like%,并且还需要使用data.table - Manuel Bickel
你是否关心部分匹配的顺序?在路线1中,你可能有“c d e”,而在路线2中,你可能有两个条目,如“b c d e”和“c d e f”。这两个条目都应该匹配吗?如果这两个路线2的条目有不同的轨迹,应该如何处理? - Manuel Bickel
“x y z” 匹配了轨道A和B。您如何决定想要哪个规则? - dww
显示剩余3条评论
3个回答

1
在data.table语法中,我们可以这样做:

library(data.table)
setDT(df1)
setDT(df2)
df1[, Track := df1[, df2[grepl(Route1, df2$Route2), Track[1]], 1:NROW(df1)][,V1]]

请注意,如果任何一行找到了多个“Track”匹配项,则假定将使用第一个匹配项。

0
有些取巧的解决方案,但仍然有效。
library(tidyverse)

df1 <- tribble(
  ~route1,
  "x y z",
  "w x f z",
  "a b c",
  "x y z"
)

find_route_match <- function(string, df2){
  df2[str_detect(df2$route2, string), 2] %>% as.character()
}

df2 <- tribble(
  ~route2,        ~track,
  "x y z",        "A",
  "v w x f z",    "B",
  "a b",          "C"
)

df1 %>% 
  mutate(match = map(route1, find_route_match, df2)) %>% 
  unnest()

它会产生以下输出:

# A tibble: 4 x 2
   route1        match
    <chr>        <chr>
1   x y z            A
2 w x f z            B
3   a b c character(0)
4   x y z            A

0

也许你可以尝试使用fuzzyjoin包:

library(fuzzyjoin)

regex_right_join(df2, df1, by = c(Route2 = 'Route1'))
#      Route2 Track  Route1
# 1     x y z     A   x y z
# 2 v w x f z     B w x f z
# 3      <NA>  <NA>   a b c
# 4     x y z     A   x y z

可重现的数据:

df1 <- structure(list(Route1 = c("x y z", "w x f z", "a b c", "x y z"
)), .Names = "Route1", class = "data.frame", row.names = c(NA, -4L))

df2 <- structure(list(Route2 = c("x y z", "v w x f z", "a b"), Track = c("A",
"B", "C")), .Names = c("Route2", "Track"), row.names = c(NA,
-3L), class = "data.frame")

df1
#    Route1
# 1   x y z
# 2 w x f z
# 3   a b c
# 4   x y z

df2
#      Route2 Track
# 1     x y z     A
# 2 v w x f z     B
# 3       a b     C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接