使用data.table来选择非唯一行

我有一个由几个基因(newID)和相关值组成的大表。一些基因(newID)是唯一的,一些基因(多个行)。如何从表中排除那些只有一个事件(行)?在下面的例子中,只有最后一行会被删除,因为它是唯一的。使用data.table来选择非唯一行

head(exons.s, 10) 

Row.names exonID pvalue log2fold.5_t.GFP_t. newID

1 ENSMUSG00000000001_Gnai3:E001 E001 0.3597070 0.029731989 ENSMUSG00000000001

2 ENSMUSG00000000001_Gnai3:E002 E002 0.6515167 0.028984837 ENSMUSG00000000001

3 ENSMUSG00000000001_Gnai3:E003 E003 0.8957798 0.009665072 ENSMUSG00000000001

4 ENSMUSG00000000001_Gnai3:E004 E004 0.5308266 -0.059273822 ENSMUSG00000000001

5 ENSMUSG00000000001_Gnai3:E005 E005 0.4507640 -0.061276835 ENSMUSG00000000001

6 ENSMUSG00000000001_Gnai3:E006 E006 0.5147357 -0.068357886 ENSMUSG00000000001

7 ENSMUSG00000000001_Gnai3:E007 E007 0.5190718 -0.063959853 ENSMUSG00000000001

8 ENSMUSG00000000001_Gnai3:E008 E008 0.8999434 0.032186993 ENSMUSG00000000001

9 ENSMUSG00000000001_Gnai3:E009 E009 0.5039369 0.133313175 ENSMUSG00000000001

10 ENSMUSG00000000003_Pbsn:E001 E001 NA NA ENSMUSG00000000003

> dim(exons.s)

[1] 234385 5

随着plyr我会去这样的:

## remove single exon genes: 

multEx <- function(df){

if (nrow(df) > 1){return(df)}

}

genes.mult.ex <- ddply(exons.s , .(newID), multEx, .parallel=TRUE)

但是,这是非常缓慢的。我想这是很容易与data.table但我无法弄清楚:

exons.s <- data.table(exons.s, key="newID") 

x.dt.out <- exons.s[, lapply(.SD, multEx), by=newID]

我是新来data.table所以在正确的方向的任何指针将受到欢迎。

回答:

创建一个列给每个组中行的数量,那么子集:

exons.s[,n:=.N,by=newID] 

exons.s[n>1]

回答:

有这样使用复制()函数,而不是计数组大小的更简单,更effiecent方式。

首先,我们需要生成一个测试dastaset:

# Generate test datasets 

smallNumberSampled <- 1e3

largeNumberSampled <- 1e6

smallDataset <- data.table(id=paste('id', 1:smallNumberSampled, sep='_'), value1=sample(x = 1:26, size = smallNumberSampled, replace = T), value2=letters[sample(x = 1:26, size = smallNumberSampled, replace = T)])

largeDataset <- data.table(id=paste('id', 1:largeNumberSampled, sep='_'), value1=sample(x = 1:26, size = largeNumberSampled, replace = T), value2=letters[sample(x = 1:26, size = largeNumberSampled, replace = T)])

# add 2 % duplicated rows:

smallDataset <- rbind(smallDataset, smallDataset[sample(x = 1:nrow(smallDataset), size = nrow(smallDataset)* 0.02)])

largeDataset <- rbind(largeDataset, largeDataset[sample(x = 1:nrow(largeDataset), size = nrow(largeDataset)* 0.02)])

然后我们实现三个解决方案的功能:

# Original suggestion 

getDuplicatedRows_Count <- function(dt, columnName) {

dt[,n:=.N,by=columnName]

return(dt[n>1])

}

# Duplicated using subsetting

getDuplicatedRows_duplicated_subset <- function(dt, columnName) {

return(dt[which(duplicated(dt[,columnName, with=FALSE]) | duplicated(dt[,columnName, with=FALSE], fromLast = T) ),])

}

# Duplicated using the "by" argument to avoid copying

getDuplicatedRows_duplicated_by <- function(dt, columnName) {

return(dt[which(duplicated(dt[,by=columnName]) | duplicated(dt[,by=columnName], fromLast = T) ),])

}

然后我们测试,他们给了相同的结果

results1 <- getDuplicatedRows_Count  (smallDataset, 'id') 

results2 <- getDuplicatedRows_duplicated_subset(smallDataset, 'id')

results3 <- getDuplicatedRows_duplicated_by(smallDataset, 'id')

> identical(results1, results2)

[1] TRUE

> identical(results2, results3)

[1] TRUE

而我们时间3种解决方案的平均表现:

# Small dataset 

> system.time(temp <- replicate(n = 100, expr = getDuplicatedRows_Count (smallDataset, 'id')))/100

user system elapsed

0.00176 0.00007 0.00186

> system.time(temp <- replicate(n = 100, expr = getDuplicatedRows_duplicated_subset(smallDataset, 'id')))/100

user system elapsed

0.00206 0.00005 0.00221

> system.time(temp <- replicate(n = 100, expr = getDuplicatedRows_duplicated_by (smallDataset, 'id')))/100

user system elapsed

0.00141 0.00003 0.00147

#Large dataset

> system.time(temp <- replicate(n = 100, expr = getDuplicatedRows_Count (largeDataset, 'id')))/100

user system elapsed

0.28571 0.01980 0.31022

> system.time(temp <- replicate(n = 100, expr = getDuplicatedRows_duplicated_subset(largeDataset, 'id')))/100

user system elapsed

0.24386 0.03596 0.28243

> system.time(temp <- replicate(n = 100, expr = getDuplicatedRows_duplicated_by (largeDataset, 'id')))/100

user system elapsed

0.22080 0.03918 0.26203

这表明duplicate()方法的缩放比例更好,尤其是在使用“by =”选项的情况下。

UPDATE:11月21日相同的输出(如建议的阿伦 - 感谢)在2014年测试使用data.table v 1.9.2中发现的问题与我在哪里,重复的fromLast不起作用。我更新到v 1.9.4并重新分析,现在差异小得多。

UPDATE:2014年11月26日。包含并测试了“by =”方法从data.table中提取列(正如Arun所建议的,因此信用额度已达到此值)。此外,对运行时间的测试在100次测试中取平均值,以确保结果的正确性。

以上是 使用data.table来选择非唯一行 的全部内容, 来源链接: utcz.com/qa/257547.html

回到顶部