【问题标题】:create data.table column in pipe with grepl使用 grepl 在管道中创建 data.table 列
【发布时间】:2018-10-04 00:49:35
【问题描述】:

我正在寻找一种在管道序列中创建新的data.table 列的方法,使用grepl 查找特定字符串的任何出现。

我已向herehere 寻求帮助,似乎有很多关于这个主题的问题,但似乎并没有直接解决我的问题。

另外,我可能误解了data.table 的语法并引用了Reference semantics vignettes。我有下面的代码,其中有两种方法可以通过管道/链接但似乎不起作用。明确创建data.table 列的最后一个选项似乎有效,但我想知道它是否可以链接/管道。

据我了解,在data.table 中使用lapply 会将函数应用于整个列(即summeanna.approx,我从另一个发布的问题中发现)但不会起作用在逐行的基础上。此外,我可以使用new_col := function(x) 将函数应用于给定列中的每一行。所以我会认为其中之一可以工作。

我(只是有点)知道grepl 需要一个值,但提供了一个向量,我不确定如何解决这个问题。

感谢您的帮助。

> library(data.table)
> 
> a = c("housefly",
+       "house fly",
+       "HOUSEFLY",
+       "HOUSE FLY")
> 
> dt = data.table(insect = c("housefly",
+                            "house fly",
+                            "HOUSEFLY",
+                            "HOUSE FLY",
+                            "dragonfly",
+                            "dragon fly"))
> 
> # does not work but I could put this in chain/pipe
> dt[, fly_check := sapply(.SD, grepl, paste(a, collapse = "|")), .SDcols = "insect"]
Warning message:
In FUN(X[[i]], ...) :
  argument 'pattern' has length > 1 and only the first element will be used
> dt
       insect fly_check
1:   housefly      TRUE
2:  house fly      TRUE
3:   HOUSEFLY      TRUE
4:  HOUSE FLY      TRUE
5:  dragonfly      TRUE
6: dragon fly      TRUE
> 
> # does not work but I could put this in chain/pipe
> dt[, fly_check := ifelse(grepl(insect, paste(a, collapse = "|")), TRUE, FALSE)]
Warning message:
In grepl(insect, paste(a, collapse = "|")) :
  argument 'pattern' has length > 1 and only the first element will be used
> dt
       insect fly_check
1:   housefly      TRUE
2:  house fly      TRUE
3:   HOUSEFLY      TRUE
4:  HOUSE FLY      TRUE
5:  dragonfly      TRUE
6: dragon fly      TRUE
> 
> # works but can't be chained/piped
> dt$fly_check = sapply(dt$insect, grepl, pattern = paste(a, collapse = "|"))
> dt
       insect fly_check
1:   housefly      TRUE
2:  house fly      TRUE
3:   HOUSEFLY      TRUE
4:  HOUSE FLY      TRUE
5:  dragonfly     FALSE
6: dragon fly     FALSE

【问题讨论】:

  • 抱歉,应该更清楚地说明预期的结果。它是代码输出中最后打印的dt。如果昆虫列包含字符串“fly”,我正在寻找 fly_check 列以返回 TRUE
  • 相信你在找:dt[, fly_check := (Vectorize(grepl)(paste0(a, collapse = "|"),.SD)), .SDcols = c("insect")]
  • 没问题!这样可行。你发我会标记的。感谢您对@chinsoon12 的快速回复......现在还有其他人。
  • @chinsoon12 如果您将您的评论作为解决方案发布,我会将其标记为正确,因为您是第一个回复的...

标签: r data.table grepl


【解决方案1】:

您似乎正在寻找这个,尽管@chinsoon12(在 cmets 中)提供了一个更简单的解决方案,它只是直接传递列名:

逻辑:在 data.table 中,如果您使用 .SD 参数调用它,则表示数据的子集,这也表明该列不是作为向量而是作为 data.table 对象传递(因此您必须使用 Vectorize 或其他操作),另一方面,如果您直接将其作为列传递,则 grepl 处理类似向量的结构没有问题(@Chinsoon12 解决方案)。

您可以查看this,这是一个非常有启发性的链接。

dt[, fly_check := (Vectorize(grepl)(paste0(a, collapse = "|"),.SD)), .SDcols = c("insect")]

导致:

#       insect fly_check
#1:   housefly      TRUE
#2:  house fly      TRUE
#3:   HOUSEFLY      TRUE
#4:  HOUSE FLY      TRUE
#5:  dragonfly     FALSE
#6: dragon fly     FALSE

【讨论】:

    【解决方案2】:

    我认为这只是%in%a 值的简单应用

    dt[ , fly_check := insect %in% a]
    

    这似乎比将grepl 应用于折叠的a 值作为模式更简单。

    dt[ , fly_check := grepl( paste0(a, collapse="|") , insect)]
    
    > dt
           insect fly_check
    1:   housefly      TRUE
    2:  house fly      TRUE
    3:   HOUSEFLY      TRUE
    4:  HOUSE FLY      TRUE
    5:  dragonfly     FALSE
    6: dragon fly     FALSE
    

    我想如果您对ignore.case=TRUE 或“perl”或“固定”参数提供的所需设施具有普遍性,您可能仍会选择grepl 策略。

    【讨论】:

      猜你喜欢
      • 2020-01-23
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-10
      • 1970-01-01
      相关资源
      最近更新 更多