【问题标题】:How can I get the names of rows in a data.table satisfying a regex condition?如何获取满足正则表达式条件的 data.table 中的行名称?
【发布时间】:2019-05-10 13:55:50
【问题描述】:

假设我有一个 data.table 如下:

data=data.table(dates=c('04 SEPTEMBER 2018', '05 APR 2018', '7/10/2018'), DT = c('21/07/2010', '3 04 2018', '16 DEC 2018'), amounts = c(21,37,49))

我想要 data.table 中满足以下 grep 条件的行的名称

grepl("^[0-9]{2}\\s[A-Z]{3}\\s[0-9]{4}",x) 

这样我就可以找到日期满足特定日期格式的行。如您所见,datesDT 两列都包含日期格式。我不想引用代码中的特定列。我只想选择包含与上述 grep 模式匹配的字符的行。

我希望正确的代码返回c(2,3),因为这些行包含所需的字符串。我怎样才能得到我期望的答案?

【问题讨论】:

  • 试试which(grepl("^[0-9]{2}\\s[A-Z]{3}\\s[0-9]{4}", data$dates))grep("^[0-9]{2}\\s[A-Z]{3}\\s[0-9]{4}", data$dates)
  • 我更愿意在不具体引用特定列名的情况下获取名称。我假设我不知道包含日期的列的名称。
  • 这是一个完全不同的问题。在您的尝试中,您也可以参考列名dates
  • 我会进行必要的编辑
  • 你的问题还是很模糊。我们如何知道该列?所有其他列都是数字和date 字符吗?它总是在数据集中的特定位置吗?请尝试并明确。除非您想将其应用于每一列...??

标签: r data.table


【解决方案1】:

使用lapply() 确定哪些列与正则表达式匹配。由于lapply() 输出的是一个列表,所以使用Reduce(`|`, ...) 来验证每行是否至少有一个列满足regexpr 条件:

data[
  data[, Reduce(`|`, lapply(.SD, function(x) grepl("^[0-9]{2}\\s[A-Z]{3}\\s[0-9]{4}",x)))], 
  ]

结果:

> data[
+   data[, Reduce(`|`, lapply(.SD, function(x) grepl("^[0-9]{2}\\s[A-Z]{3}\\s[0-9]{4}",x)))], 
+   ]
         dates amounts
1: 05 APR 2018      37
2: 16 DEC 2018      49

更新

获取匹配的行的索引(对于任何列):使用sapply() 获取一个矩阵,其中包含指示匹配是否成功的单元格。然后使用rowSums(...) > 0 将其合并为一个值为TRUE(行中至少有一个单元格匹配成功)或FALSE(根本没有匹配)的向量。将其全部包裹在 which() 中以显示行索引。

结果:

> which(rowSums(sapply(data,function(x) grepl("^[0-9]{2}\\s[A-Z]{3}\\s[0-9]{4}",x))) > 0)
[1] 2 3

【讨论】:

  • 不幸的是,这不会返回行索引 2 和 3,这是解决方案
  • 是吗?结果在哪一列?您的结果似乎是行本身而不是它们的索引
  • 它返回第 2 行和第 3 行,是的。你到底在找什么?实际的索引“2”和“3”?
  • 我得到的是 c(1,2) 而不是 c(2,3)
  • 好的,所以您希望输出为"2" "3"?它返回与正则表达式匹配的行。不确定是要返回行索引还是行。
【解决方案2】:

另一种 data.table 方法:

ans <- melt( transpose(data), 
             id.vars = NULL, 
             measure.vars = patterns("^V"), 
             variable.name = "row" )
ans <- ans[ grepl("^[0-9]{2}\\s[A-Z]{3}\\s[0-9]{4}", value), ]
ans[, row := gsub("V", "", row)]
    row       value
 1:   2 05 APR 2018
 2:   3 16 DEC 2018

更新

data[ seq.int(.N) %in% ans$row, ]
          dates          DT amounts
 1: 05 APR 2018   3 04 2018      37
 2:   7/10/2018 16 DEC 2018      49

【讨论】:

  • 有没有办法只获取行?
  • 抱歉,我的意思是没有实际行的行名......对不起,这是我的错误
  • data.table 不支持行名(这是我一直被告知的)。
  • 如果你只想要行号,使用ans$row...它返回c("2","3")
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-13
  • 1970-01-01
  • 1970-01-01
  • 2022-07-21
  • 1970-01-01
  • 1970-01-01
  • 2015-03-21
相关资源
最近更新 更多