簡體   English   中英

用data.table R選擇行或列?

[英]Selecting rows or columns with data.table R?

想象一下,我有一個data.table,例如:

library(data.table) 
RRR <-data.table(1:15,runif(15),rgeom(15,0.5),rbinom(15,2,0.5))

    V1      V2    V3  V4
 1:  1 0.33577273  0  0
 2:  2 0.66739739  2  1
 3:  3 0.07501655  0  0
 4:  4 0.43195663  2  1
 5:  5 0.39525841  3  2
 6:  6 0.15189738  1  1
 7:  7 0.02637279  0  1
 8:  8 0.44165623  0  1
 9:  9 0.98710570  2  0
10: 10 0.62402805  1  0
11: 11 0.84829465  3  2
12: 12 0.02170976  0  1
13: 13 0.74608925  0  2
14: 14 0.29102296  2  0
15: 15 0.83820646  1  1

如何從中獲取data.table,所有ROWS在任何列都包含“0”? (或一些價值)
如果我必須使用單個列,我可以使用:

RRR[V4==0,]

   V1    V2      V3  V4
1:  1 0.33577273  0  0
2:  3 0.07501655  0  0
3:  9 0.98710570  2  0
4: 10 0.62402805  1  0
5: 14 0.29102296  2  0

但是,如果我想同時使用所有列,因為我有很多?

這不符合我的需要。

RRR[,sapply(RRR,function(xx)(xx==0)), with=TRUE]   

     V1      V2     V3    V4
[1,]  FALSE FALSE  TRUE  TRUE
[2,]  FALSE FALSE FALSE FALSE
[3,]  FALSE FALSE  TRUE  TRUE
[4,]  FALSE FALSE FALSE FALSE
[5,]  FALSE FALSE FALSE FALSE
[6,]  FALSE FALSE FALSE FALSE
[7,]  FALSE FALSE  TRUE FALSE
[8,]  FALSE FALSE  TRUE FALSE
[9,]  FALSE FALSE FALSE  TRUE
[10,] FALSE FALSE FALSE  TRUE
[11,] FALSE FALSE FALSE FALSE
[12,] FALSE FALSE  TRUE FALSE
[13,] FALSE FALSE  TRUE FALSE
[14,] FALSE FALSE FALSE  TRUE
[15,] FALSE FALSE FALSE FALSE

也許用for循環和一些復雜的粘貼? 雖然,我更喜歡使用簡單的data.table語法。

同樣,你如何獲得一個data.table,其中包含任何行中包含'0'的所有COLUMNS?

我知道如何獲得滿足條件的列(作為一個整體),例如數字,

RRR[,sapply(RRR,function(xx)is.numeric(xx)),with=FALSE]

但是如果我想要元素測試條件,這個方法不起作用。


如果有人感興趣,這是一個更大的隨機數據的system.time()。使用您提供的不同解決方案到目前為止,稍作修改。

set.seed(1)
n <- 1000000
RRR <- data.table(matrix(rgeom(100*n,0.5), ncol=100))

Getting ROWS   
> RRR[RRR[,rowSums(RRR==0)>0]] 
   user  system elapsed 
   2.72    0.55    3.27 
> RRR[rowSums(RRR==0)>0] 
   user  system elapsed 
   2.58    0.70    3.28 
> RRR[apply(RRR,MAR=1,function(xx)any(xx==0))]
   user  system elapsed 
   10.81    0.19   11.00       
> RRR[apply(RRR[,paste0('V',1:ncol(RRR)),with=FALSE],function(xx)any(xx==0),MAR=1)]
  user  system elapsed 
  10.49    0.30   10.83 

Getting COLUMNS
> RRR[,sapply(RRR,function(xx)any(xx==0)), with=FALSE] 
   user  system elapsed 
   0.81    0.31    1.12 
> `[.listof`(RRR,colSums(RRR==0)>0) 
   user  system elapsed 
   2.14    0.27    2.41 
> RRR[,colSums(RRR==0)>0, with=FALSE] 
   user  system elapsed 
   2.26    0.48    2.75 
> RRR[, .SD, .SDcols=sapply(RRR, function(x) any(x==0))]      #only version 1.9.5, seems the same solution than the first one.
   user  system elapsed 
   0.78    0.36    1.14 
> RRR[, .SD, .SDcols=sapply(RRR, function(x) any(!as.logical(x)))]
   user  system elapsed 
   0.41    0.25    0.66 
> RRR[Reduce('|',lapply(RRR,function(xx)(xx==0)))]
   user  system elapsed 
   3.11    0.33    3.44 
> RRR[,apply(RRR[,paste0('V',1:ncol(RRR)),with=FALSE],function(xx)any(xx==0),MAR=2),with=FALSE]
   user  system elapsed 
   3.48    0.80    4.28  

我還沒有包括在內:

RRR[, i := any(unlist(lapply(.SD, function(x) x==0))), seq_len(nrow(RRR))][i==TRUE][,i:=NULL]   

花了幾分鍾我停了下來,它“標記”行而不是提取它們,這是最復雜的解決方案。

我會等待更快或更簡單的解決方案,並聽取您的意見和喜好。

sapply原本應該慢一點,但事實並非如此。 如果data.table包含其他類型的數據,結果可能會更改。


如果我們可以在每一行或每列中發生第一次發生時立即停止測試(== 0),我們就可以加快速度。 但我想我們不能沒有循環或一些低級訪問或按位操作。

我想到了一種新方法。

  1. sapply(RRR,函數(XX)其中(XX == 0))
  2. 我需要將a)的結果與列表的並集結合起來,但我不知道如何為任意數量的列做到這一點。
  3. 然后得到那些行RRR [“a)”]

我想如果零的數量很大,它會慢得多。

也許還嘗試RRR[unique(unlist(sapply(RRR,function(xx)which(xx==0))))]但它太慢了。

相反的選擇是RRR[(RRR==0)] <- NA; na.omit(RRR) RRR[(RRR==0)] <- NA; na.omit(RRR)

這里可以使用rowSums函數:

RRR[rowSums(!RRR)>0]

工作原理: !RRR是一個矩陣,任何零都為TRUE 在一般情況下,您可以使用要檢查的邏輯條件替換!RRR 例如,要查看是否有任何元素等於3 ,您可以采用RRR==3rowSums

我認為rowSums(test(x))>0apply(RRR,1,function(x)any(!test(x))) ; 都將對象強制轉換為矩陣。 我發現rowSums版本更容易閱讀,並認為我聽到人們稱贊它的效率。


對於列,類似地:

RRR[, colSums(!RRR)>0, with=FALSE]

也許這個。

library(data.table) 
RRR <-data.table(1:15,runif(15),rgeom(15,0.5),rbinom(15,2,0.5))
RRR[, i := any(unlist(lapply(.SD, function(x) x==0))), seq_len(nrow(RRR))
    ][i==TRUE
      ][,i:=NULL]

擴展問題第二部分的答案。

 RRR[, .SD, .SDcols=sapply(RRR, function(x) any(x==0))]
 # you may add this one also to timing, I wonder how it will work
 RRR[, .SD, .SDcols=sapply(RRR, function(x) any(!as.logical(x)))]

.SDcols作為邏輯向量最近才被引入,所以一定要先更新你的data.table。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM