-2

data.frameAとAのサブセットを含むdata.frameBがあります

data.frameBを除外したdata.frameAであるdata.frameCを作成するにはどうすればよいですか?ご協力いただきありがとうございます。

4

6 に答える 6

3

BにないAの行を取得します

C = A[! data.frame(t(A)) %in% data.frame(t(B)), ]
于 2012-04-28T20:23:25.227 に答える
2

このBデータセットが本当に最初のデータセットのネストされたバージョンである場合、最初にこのデータセットを作成したインデックスが必要です。私見では、データセット間の違いについて説明するのではなく、最初にBデータセットを作成した元のインデックスを否定する必要があります。これが私が意味することの例です:

A <- mtcars
B <- mtcars[mtcars$cyl==6, ]
C <- mtcars[mtcars$cyl!=6, ]
于 2012-04-28T21:43:25.580 に答える
1

data.tableこれがメモリと時間効率の良い2つのソリューションです

render_markdown(strict = T)
library(data.table)
# some biggish data
set.seed(1234)
ADT <- data.table(x = seq.int(1e+07), y = seq.int(1e+07))

.rows <- sample(nrow(ADT), 30000)
# Random subset of A in B
BDT <- ADT[.rows, ]

# set keys for fast merge
setkey(ADT, x)
setkey(BDT, x)
## how CDT <- ADT[-ADT[BDT,which=T]] the data as `data.frames for fastest
## alternative
A <- copy(ADT)
setattr(A, "class", "data.frame")
B <- copy(BDT)
setattr(B, "class", "data.frame")
f2 <- function() noBDT <- ADT[-ADT[BDT, which = T]]
f3 <- function() noBDT2 <- ADT[-BDT[, x]]
f1 <- function() noB <- A[-as.integer(rownames(B)), ]

library(rbenchmark)
benchmark(base = f1(),DT = f2(), DT2 = f3(), replications = 3)

##   test replications elapsed relative user.self sys.self 
## 2   DT            3    0.92    1.108      0.77     0.15       
## 1  base           3    3.72    4.482      3.19     0.52        
## 3  DT2            3    0.83    1.000      0.72     0.11     
于 2012-10-08T05:59:01.533 に答える
1
A <- data.frame(x = 1:10, y = 1:10)
#Random subset of A in B
B <- A[sample(nrow(A),3),]
#get A that is not in B
C <- A[-as.integer(rownames(B)),]

mplourdeの回答に対するパフォーマンステスト:

library(rbenchmark)
f1 <- function() A[- as.integer(rownames(B)),]
f2 <- function() A[! data.frame(t(A)) %in% data.frame(t(B)), ]
benchmark(f1(), f2(), replications = 10000, 
          columns = c("test", "elapsed", "relative"),
          order = "elapsed"
          )

  test elapsed relative
1 f1()   1.531   1.0000
2 f2()   8.846   5.7779

行名を確認すると、約6倍高速になります。転置を2回呼び出すと、計算コストが高くなる可能性があります。

于 2012-04-28T20:30:21.397 に答える
1

Bが本当にAのサブセットである場合、これを確認できます。

if(!identical(A[rownames(B), , drop = FALSE], B)) stop("B is not a subset of A!")

次に、行名でフィルタリングできます。

C <- A[!rownames(A) %in% rownames(B), , drop = FALSE]

また

C <- A[setdiff(rownames(A), rownames(B)), , drop = FALSE]
于 2012-04-28T20:44:34.497 に答える
0

これは最速ではなく、非常に遅い可能性がありますが、行データを考慮に入れ、flodelが批判した混合データで機能するmplourdeの代替手段です。これは、enxt月または2以内にリリースする予定であるため、まだ存在しないqdapパッケージのpaste2関数に依存しています。

貼り付け2機能:

paste2 <- function(multi.columns, sep=".", handle.na=TRUE, trim=TRUE){

    if (trim) multi.columns <- lapply(multi.columns, function(x) {
            gsub("^\\s+|\\s+$", "", x)
        }
    )

    if (!is.data.frame(multi.columns) & is.list(multi.columns)) {
        multi.columns <- do.call('cbind', multi.columns)
      }

    m <- if(handle.na){
                 apply(multi.columns, 1, function(x){if(any(is.na(x))){
                       NA
                 } else {
                       paste(x, collapse = sep)
                 }
             }
         )   
         } else {
          apply(multi.columns, 1, paste, collapse = sep)
    }
    names(m) <- NULL
    return(m)
}

#Flodelの混合データセット:

A <- data.frame(x = 1:4, y = as.character(1:4)); B <- A[1:2, ]

#私のアプローチ:

A[!paste2(A)%in%paste2(B), ]
于 2012-04-28T21:22:41.667 に答える