【问题标题】:data.frame filtering function too slowdata.frame 过滤功能太慢
【发布时间】:2016-03-15 20:59:32
【问题描述】:

我正在尝试使用 R 过滤我的数据框,大约有 20 万行。 数据框的结构如下:

testdf<- data.frame("CHROM"='CHR8', "POS"=c(500,510), "ID"='Some_value',
                        "REF"=c('A','C'), "ALT"=c('C','T,G'), "Some_more_stuff"='More_info')

我正在尝试根据“ALT”列中的字母数(等于或小于自定义阈值)过滤行。在上面的示例中,如果我的阈值为 1,则仅保留第一行(第二行 - ALT 列 - 有 2 个字母 > 1)。

我已经编写了几个函数来完成这项工作。唯一的问题是它们在只有 14 行的测试数据帧上需要几秒钟。在真实的数据框(200,000 行)上,它需要永远。我正在寻找有关如何编写更好的语法并获得更快结果的建议。 这是我的功能:

# Function no. 1:
allele_number_filtering<- function (snp_table, max_alleles=1, ALT_column=5) {
  #here I calculate how many letters are in the ALT column
  alt_allele_list_length <- function(ALT_field) {
    alt_length<- length(strsplit(as.character
                                 (ALT_field), split = ',')[[1]])
    return(alt_length)}
  # Create an empty dataframe with same columns as the input df
  final_table<- snp_table[0,]
  # Now only retain the rows that are <= max_alleles
  for (i in 1:nrow(snp_table)) {
    if (alt_allele_list_length(snp_table[i, ALT_column]) <= max_alleles) {
      final_table<- rbind(final_table, snp_table[i,])}}
  return(final_table)}

#Function no. 2:
allele_number_filtering<- function (snp_table, max_alleles=1, ALT_column=5) {
  final_table<- snp_table[0,]
  for (i in 1: nrow(snp_table)) {
    if (length(strsplit(as.character(snp_table[i,ALT_column]),
                        split = ',')[[1]])<=max_alleles) {
      final_table<- rbind(final_table, snp_table[i,])
    }}
  return(final_table)}

如果您有任何建议,我将不胜感激 :) 最大

编辑:我意识到我也有诸如 'ALT' = 'at' (仍算作 1)或 'ALT' = 'aa,at' (算作 2 )之类的值。

【问题讨论】:

  • 如果您不介意从 ALT 列中删除逗号,您也可以在一行中使用 nchar
  • 即使不删除逗号它也应该可以工作。在这种情况下,您需要将(n-1) 添加到您的门槛。
  • @sgibb,假设最多有两个字符
  • @docendodiscimus 你说对了一部分,这将假设一个字母代码(因为它是用于 dna 碱基)除以逗号。

标签: r filter dataframe


【解决方案1】:

您可以为此使用lengths()

testdf[lengths(strsplit(as.character(testdf$ALT), ',',fixed = TRUE))<=1,]

感谢@docendodiscimus 提供strsplit( fixed=TRUE) 选项以加快速度,感谢@joran 的洞察力

【讨论】:

  • 太好了,谢谢!我刚试了一下,速度非常快!如果逗号分隔字符组,它也可以工作,例如'ALT' = 'aa,at' 还是算2,就是我需要的
  • 我没有建议fixed = TRUE。 ;)
【解决方案2】:

我会为此使用nchar(在我通过gsub 删除, 之前):

nchar(gsub(",", "", as.character(testdf$ALT)))
# [1] 1 2

threshold <- 1
testdf[nchar(gsub(",", "", as.character(testdf$ALT))) > threshold, ]
#   CHROM POS         ID REF ALT Some_more_stuff
# 2  CHR8 510 Some_value   C T,G       More_info

【讨论】:

  • 谢谢你,sgibb!回顾我的数据集,我意识到我也有诸如 'ALT' = 'at' (仍算作 1)或 'ALT' = 'aa,at' (算作 2 )之类的值。这就是为什么我选择了 Huber 的答案。我的错,在我编辑之前你们都回答了。再次感谢您的帮助:)
猜你喜欢
  • 2020-11-12
  • 1970-01-01
  • 1970-01-01
  • 2012-03-26
  • 2020-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多