我正在尝试使用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个字母&gt; 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)等值。
答案 0 :(得分:3)
您可以使用lengths()
:
testdf[lengths(strsplit(as.character(testdf$ALT), ',',fixed = TRUE))<=1,]
感谢@docendodiscimus加快strsplit( fixed=TRUE)
选项以及@joran的敏捷性
答案 1 :(得分:3)
我会使用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