【问题标题】:Find a row in a data.table that is same as the header在 data.table 中查找与表头相同的行
【发布时间】:2020-07-08 01:46:07
【问题描述】:

我正在阅读带有 fread 的巨大 csv 文件。数据格式不正确,并且标题不时重复。我现在想删除文件中的标题,因此,我必须搜索内容等于标题的行。

我可以想到两种解决方案,但都不是最优的:

  1. 选项 1 假定所有非标题重复行至少在一个位置上相互不同
  2. 选项 2 非常冗长,需要大量写作

基本上我需要一种循环遍历所有列并将它们与标题进行比较。

因此,整个事情归结为一个问题:

如何在数据表中找到特定行无需硬编码过滤器?

代码

library(data.table)
foo <- data.frame(a = c(1:2, "a", 1:2, "a"), b = c(letters[1:2], "b", letters[2:1], "b"),
                  stringsAsFactors = FALSE)
setDT(foo)

## option 1: use duplicates, assuming that each row is otherwise unique
foo[-(which(duplicated(rbind(as.list(names(foo)), foo))) - 1)]

## option 2: compare directly, but becomes very cumbersome with growing number of columns
foo[!(a == names(foo)[1] & b == names(foo)[2])]

【问题讨论】:

  • 重复的标题总是与实际的第一个标题相同?
  • 据我所知是的
  • 那我们只需要比较第一列,即你的选项2,但只检查第一列?或者使用 grep 删除 R 外部的标头,例如 fread("grep -v myCol1 myfile.txt")
  • 有趣的想法。我还考虑了外部 R 选项,但对于可重复性和文档,我希望在 R 中完成所有事情。只查看第一个(几个)标题是有趣和聪明的,并且肯定适用于现有的数据。
  • @thothal 有一种方法可以在 R 中传递这样的命令,正如 zx8754 所示

标签: r data.table fread


【解决方案1】:

反加入:

setkeyv(foo, names(foo)) # Reordes data though
foo[!list(names(foo))]

   a b
1: 1 a
2: 1 b
3: 2 a
4: 2 b

无需设置键:

nfoo <- names(foo)
foo[!setNames(as.list(nfoo), nfoo), on = nfoo]

【讨论】:

  • 漂亮整洁。将所有列设置为键是否被认为是一种好的做法,或者以后使用这种技术会引入一些陷阱?
  • @thothal 我能想到的唯一陷阱是它会重新排序数据,无论如何最好避免它。发布了一个新的可能性。
【解决方案2】:

由于错位的标题与实际标题重复相同,因此我们只需要比较第一列,即您的选项 2,但只检查第一(或任何)列:

foo[ !(a == names(foo)[1]), ]

或使用 grep 删除 R 外部的标头,例如:

fread("grep -v myCol1 myfile.txt")

或者粘贴每一行,与表头比较:

foo[ do.call(paste, c(foo, list(sep = "_"))) != paste(colnames(foo), collapse = "_"), ]

我更喜欢使用第二个选项,这样我们就不会遇到使用其他“after-fread”解决方案时遇到的列类问题。

【讨论】:

  • 感谢您的回答,因为数据也是错误的,否则我需要进行一些繁重的数据清理。但我喜欢grep 选项。根据您的直觉,grep 和 sindri 的 anti_join 哪个解决方案更快?
  • 对于grep,我会将regex 更改为^myCol1,以避免我们过滤掉myCol1 合法出现的行。
  • @thothal 我主要关心的不是速度,而是列类变得混乱,我会 grep clean 然后让 fread 修复我的列类。直觉:grep 可能会赢。
  • @thothal yes grep 只是一个例子,您需要测试什么正则表达式最适合您的真实数据。
  • 这很有趣。它可以在任何机器上运行吗?
猜你喜欢
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 2011-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多