【问题标题】:efficient way to delete rows of big dataset in R在R中删除大数据集行的有效方法
【发布时间】:2020-12-28 02:00:31
【问题描述】:

我正在使用包含 803 个变量的大型数据集 562792 obj 我想根据第六个变量的值对我的数据进行子集化

我的数据集如下所示:(只有 5*10 的数据集子集)

           seq  start    end   name     score annotation        GC         NA       NA.1
PCPG_2 chr1  17238  17739 PCPG_2  4.406228   Promoter 0.6127745  0.4791137  0.4321641
LIHC_2 chr1 102709 103210 LIHC_2  3.472406     Intron 0.4491018 -1.4821049 -1.1310495
LIHC_3 chr1 136494 136995 LIHC_3  8.211594     Distal 0.7065868 -0.6996327 -0.5816772
TGCT_2 chr1 180653 181154 TGCT_2  7.718365     Distal 0.5588822  1.5983810  1.6995938
LGG_2  chr1 181202 181703  LGG_2 67.948112     Distal 0.7584830  2.9480593  3.2586839
             NA.2
PCPG_2  0.5570205
LIHC_2 -1.3443903
LIHC_3 -1.5895320
TGCT_2  1.6474305
LGG_2   1.7238597

基本上我想删除带有“Promoter”注释的行。我使用此代码根据“注释”变量对我的数据进行了子集化

promoters<-which(dataset[,6]=="Promoter")
dataset[-promoters,]

然后 R 弯腰响应并崩溃 我还使用了命令 subset 并且 R 会话停止工作。 由于我是 R 新手,我无法准确检测到问题,但我认为这是因为这个大数据占用了太多内存。 谁能帮我解决这个问题或建议一种更有效的方法来从数据集中删除对象?

【问题讨论】:

  • dataset[ dat$annotation != "Promoter", ]subset(dataset, annotation != "Promoter") 都应该工作。您可能需要小心使用您的which 代码...如果没有找到,它将返回integer(0),并且dataset[-integer(0),] 返回零行,而不是您想要的。在这里使用logical 而不是integer 索引可能会更好;使用您的代码,dataset[!dataset[,6] == "Promoter",]dataset[dataset[,6] != "Promoter",] 也应该可以工作。
  • @r2evans 我确实尝试了dataset[ dataset[ ,6]!="Promoter", ]subset 都崩溃了。我认为那是因为我的数据集很大。我用较小的数据集尝试了这段代码,它确实有效,但在我的实际数据集上没有。
  • 我相信一般data.frames,删除一行会将整个框架复制到一个新对象中。我认为data.table 可能能够避免这种情况,但that issue 似乎仍然开放。是的,大数据肯定会带来挑战。我听说过(没有尝试过)disk.frame 的好东西,但缺乏这些......也许数据库更适合您的数据。

标签: r bigdata


【解决方案1】:

您可以使用来自 dplyrfilter()filter()subset() 稍微高效一些,并且考虑到您拥有庞大的数据集,此选项可能更有用。因此,您可以像这样使用filter()

dataset = filter(dataset, annotation != 'Promoter')

您还可以使用条件运算符(&amp;|)在filter() 中使用其他条件,例如

dataset = filter(dataset, annotation != 'Promoter' & score < 8)

Ps.:记得加载 dplyr 包 (library(dplyr)),否则 R 将调用一个也称为 filter 的基本函数。

如果您仍然遇到问题并且 R 会话崩溃,您可以按照以下步骤从终端运行您的代码:

  1. 编辑你的代码;
  2. 保存在某处;
  3. 使用命令 Rscript 从终端运行它。以下命令可能会对您有所帮助:
    1. 将目录更改为代码所在的路径,使用:`cd "directory path"
    2. 运行您的代码,使用:`Rscript your_code.R

希望对你有帮助。

【讨论】:

  • dplyr::filter“效率更高”如何?虽然它在很大程度上依赖于数据 size,但microbenchmark::microbenchmark(base=subset(diamonds, cut != "Ideal"), dplyr=filter(diamonds, cut != "Ideal")) 建议 dplyr::filter 花费 50% 的时间来做同样的事情(结果是相同的)。
  • (好吧,我明白了......当我将diamonds 扩展得更大一点时,奇偶校验发生了,dplyr::filter 在更大的一端确实快了一点......)那些关心的人,当我将diamonds 中的行加倍时,函数的性能大致相同。如果我改为将行数提高 100 倍(5M),dplyr::filtersubset 快 24%。
  • 我一直相信文献,它说dplyr::filter() 比原生subeset() 更有效。我非常感谢你检查了它,@r2evans。谢谢我的朋友!
  • @rodolfoksveiga 谢谢你的回答,很清楚。我在终端中使用filter 命令和Rscript 我收到以下错误Can't transform a data frame with duplicate names.
  • @rodolfoksveiga 回溯是 1. ├─dplyr::filter(dataset, annotation != "Promoter") 2. └─dplyr:::filter.data.frame(dataset, annotation != "Promoter") 3. └─dplyr:::filter_rows(.data, ...) 4. └─DataMask$new(.data, caller_env()) 5. └─.subset2(public_bind_env, "initialize")( ...)
猜你喜欢
  • 2013-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-17
  • 1970-01-01
相关资源
最近更新 更多