regex - 快速测试 R 数据框以查看一列中的行值是否在数据框中的另一列内

标签 regex r dataframe data.table apply

我有一个包含 22k 条记录和 6 列的营销数据数据框,其中 2 列是感兴趣的。

  • 变量
  • FO.variable

  • 这是数据帧样本的 dput 输出的链接:http://dpaste.com/2SJ6DPX

    请让我知道是否有更好的方式来共享这些数据。

    我想要做的就是创建一个额外的二进制保持列,它应该是:
  • 1 如果 FO.variable 在 Variable 内
  • 如果 FO.Variable 不在 Variable 内,则为 0

  • 看起来很简单……在 Excel 中,我只需添加带有“if”公式的另一列,然后将公式粘贴下来。我花了几个小时试图得到这个和 R 并失败了。

    这是我尝试过的:
  • 使用 grepl 进行模式匹配。我以前使用过 grepl,但这次我试图传递一列而不是字符串。我早期的尝试失败了,因为我试图强制使用列中的第一个值而不是整个值来强制 grepl 和 ifelse 导致 grepl。
  • 我的下一次尝试是根据 SO 上的另一篇文章使用转换和 grep。我不认为这会给我我的确切答案,但我认为它会让我足够接近我从那里弄清楚......代码运行了一段时间而不是因为无效下标而出错。
    transform(dd, Keep = FO.variable[sapply(variable, grep, FO.variable)])
  • 我的下一次尝试是使用 str_detect,但我认为这不是正确的方法,因为我想要行级值,并且我认为“any”实际上会使用向量中的任何值?
    kk <- sapply(dd$variable, function(x) any(sapply(dd$FO.variable, str_detect, string = x)))
  • 编辑:刚刚尝试了一个 for 循环。我更喜欢矢量化方法,但此时我非常绝望。我之前没有使用过 for 循环,因为我避免了它们并坚持使用其他解决方案。它似乎不太正确,不确定我是否搞砸了语法:
  • for(i in 1:nrow(dd)){ if(dd[i,4] %in% dd[i,2]) dd$test[i] <- 1 }
    正如我所提到的,如果 FO.variable 在变量内部,我的理想输出是一个带有 1 或 0 的附加列。例如,示例数据中的前三条记录将为 1,第四条记录将为 0,因为“直接/未知”不在“有机搜索,系统电子邮件”中。

    如果一个解决方案可以快速运行,那将是一个奖励。应用选项花费了很长时间,也许是因为它们在两列之间的每次迭代中循环?

    结果证明这几乎不像我想象的那么简单。或者也许是这样,而我只是个笨蛋。无论哪种方式,我都感谢有关如何最好地解决此问题的任何帮助。

    最佳答案

    我读了数据

    df = dget("http://dpaste.com/2SJ6DPX.txt")
    

    然后将“变量”列拆分为各个部分并计算出每个条目的长度
    v = strsplit(as.character(df$variable), ",", fixed=TRUE)
    len = lengths(v)    ## sapply(v, length) in R-3.1.3
    

    然后我取消了 v 并创建了一个索引,将未列出的 v 映射到它来自的行
    uv = unlist(v)
    idx = rep(seq_along(v), len)
    

    最后,我在 FO.variable 中找到了 uv 等于其对应条目的索引
    test = (uv == as.character(df$FO.variable)[idx])
    df$Keep = FALSE
    df$Keep[ idx[test] ] = TRUE
    

    或组合(返回逻辑向量似乎比修改后的 data.frame 更有用,可以使用 dd$Keep = f0(dd) 获得)
    f0 = function(dd) {
        v = strsplit(as.character(dd$variable), ",", fixed=TRUE)
        len = lengths(v)
        uv = unlist(v)
        idx = rep(seq_along(v), len)
    
        keep = logical(nrow(dd))
        keep[ idx[uv == as.character(dd$FO.variable)[idx]] ] = TRUE
        keep
    }
    

    (使用列是因子这一事实可以使速度更快,但也许这不是故意的?)与(公认的更简单,更容易理解)相比
    f1 = function(dd) 
        mapply(grepl, dd$FO.variable, dd$variable, fixed=TRUE)
    
    f1a = function(dd)
        mapply(grepl, as.character(dd$FO.variable), 
               as.character(dd$variable), fixed=TRUE)
    
    f2 = function(dd)
        apply(dd, 1, function(x) grepl(x[4], x[2], fixed=TRUE))
    


    > library(microbenchmark)
    > identical(f0(df), f1(df))
    [1] TRUE
    > identical(f0(df), unname(f2(df)))
    [1] TRUE
    > microbenchmark(f0(df), f1(df), f1a(df), f2(df))
    Unit: microseconds
        expr     min       lq      mean   median       uq     max neval
      f0(df)  57.559  64.6940  70.26804  69.4455  74.1035  98.322   100
      f1(df) 573.302 603.4635 625.32744 624.8670 637.1810 766.183   100
     f1a(df) 138.527 148.5280 156.47055 153.7455 160.3925 246.115   100
      f2(df) 494.447 518.7110 543.41201 539.1655 561.4490 677.704   100
    

    在时序开发过程中,两个微妙但重要的添加是在正则表达式中使用 fixed=TRUE,并将因素强制转换为字符。

    关于regex - 快速测试 R 数据框以查看一列中的行值是否在数据框中的另一列内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29524325/

    相关文章:

    ruby - 如何使用 ruby​​ 正则表达式获取子字符串?

    r - 在 Redhat 7.5 上向 R 中的 Plumber API 端点发送主体尺寸较大的 POST 请求时出现问题

    python - 是否有一种最佳方法可以在分组的 Pandas 数据框中获取所有值组合?

    python - 使用字典值过滤数据帧,同时将字典键分配给匹配的行?

    ruby-on-rails - Ruby、gsub 和正则表达式

    regex - htaccess 外部重写/内部重定向

    c# - 正则表达式 C# - 如何匹配类的方法和属性名称

    r - 在同一个图中绘制两个图

    r - R 中列表操作的向量化列表

    r - 在R中转置data.frame并将列之一设置为新转置表的标题的最佳方法是什么?