【问题标题】:Find if a string is contained within another string in R查找一个字符串是否包含在 R 中的另一个字符串中
【发布时间】:2018-05-28 16:17:49
【问题描述】:

我正在尝试查找一个字符串是否包含在不同数据框中的另一个字符串中。我正在使用 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 是否包含在 Route 2 中,我想为 Route 1 分配相应的 Track。因此,数据帧 1 的最终数据帧应该是:

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 中。请注意,我在每个数据框中都有多个列。

感谢您的帮助

【问题讨论】:

  • 看看?merge in base R or in the data.table package如果速度是一个问题。
  • 对于合并,“路线”不需要相同吗?
  • 您是对的,抱歉,您已经看到您也在寻找部分匹配项。那么你可能还需要%like%data.table
  • 是您感兴趣的部分匹配的顺序,因此,在 Route 1 中您可能有“cde”,在 Route 2 中您可能有两个条目,如“bcde”和“cdef”,两者都应该是匹配到了,这两个Route 2入口轨迹不同的情况如何处理?
  • 'x y z' 匹配轨道 A 和 B。什么规则来决定你想要哪个?

标签: r string loops if-statement


【解决方案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 匹配项,则假定将使用第一个匹配项

【讨论】:

    【解决方案2】:

    有点老套的解决方案,但仍然有效

    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
    

    【讨论】:

      【解决方案3】:

      也许你可以试试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
      

      【讨论】:

        猜你喜欢
        • 2013-03-13
        • 2014-04-14
        • 1970-01-01
        • 1970-01-01
        • 2023-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-06
        相关资源
        最近更新 更多