5

さまざまなケースを持つ 2 つのデータ フレームがあります。時間 1 から 1 つと時間 2 から 1 つ。時間 1 と時間 2 の間に変更が発生したケースをすばやく特定する方法を探していて、ちょっと立ち往生しています。

ここに例があります。だから、私は時間1からのデータフレームを持っています、

df.t1 <- data.frame(id = c(1,1,1,2,2,3,3,5,5,6), ABC = LETTERS[1:10], Num = 101:110)

そしてそれはこのように見えます、

df.t1
   id ABC Num
1   1   A 101
2   1   B 102
3   1   C 103
4   2   D 104
5   2   E 105
6   3   F 106
7   3   G 107
8   5   H 108
9   5   I 109
10  6   J 110

時間 2 ロールアラウンド

df.t2 <- df.t1

そして、いくつかの変化が起こり、

df.t2[3,3] <- 104
df.t2[2,2] <- "H"
df.t2[8,3] <- 999
df.t2[10,3] <- NA
df.t2[11,] <- c(3, "J", 107)

これは時間 2 です。

df.t2
   id ABC  Num
1   1   A  101
2   1   H  102
3   1   C  104
4   2   D  104
5   2   E  105
6   3   F  106
7   3   G  107
8   5   H  999
9   5   I  109
10  6   J <NA>
11  3   J  107

time1 と time 2 の間にケース (任意の行) で変更が発生していないケースについて、すべての ID のケースを削除する簡単な方法を探しています。特定の例では、変更がないのは ID # 2 のみです。 1回目と2回目の間に発生。

このような最終結果を探しています。

(df <- subset(df.t2, id != 2))
   id ABC  Num
1   1   A  101
2   1   H  102
3   1   C  104
6   3   F  106
7   3   G  107
8   5   H  999
9   5   I  109
10  6   J <NA>
11  3   J  107

任意の助けをいただければ幸いです。

4

5 に答える 5

3

これはうまくいくと思います。を使用したソリューションdata.table:

require(data.table)
dt1 <- data.table(df.t1)
dt2 <- data.table(df.t2)
# your conversion made them characters
dt2[, `:=`(id = as.numeric(id), Num = as.numeric(Num))]
setkey(dt1, "id", "ABC")
setkey(dt2, "id", "ABC")
dt <- dt1[dt2]
dt2[id %in% dt[, !(all(Num == Num.1)) | any(is.na(c(Num, Num.1))), by=id][V1 == TRUE]$id]

#    id ABC Num
# 1:  1   A 101
# 2:  1   C 104
# 3:  1   H 102
# 4:  3   F 106
# 5:  3   G 107
# 6:  3   J 107
# 7:  5   H 999
# 8:  5   I 109
# 9:  6   J  NA

または、取得後dt = dt1[dt2]:

dt2[id %in% dt[, ctr := Num %in% Num.1, by=1:nrow(dt)][ctr == FALSE, unique(id)]]
于 2013-02-14T00:52:54.000 に答える
3

data.table の使用とid、 、ABCおよびNUM

require(data.table)
dt1 <- data.table(df.t1)
dt2 <- data.table(df.t2)
# your conversion made them characters
dt2[, `:=`(id = as.numeric(id), Num = as.numeric(Num))]
setkey(dt1, "id", "ABC", "Num")
setkey(dt2, "id", "ABC", "Num")
# then it is just

dt2[dt2[!dt1][,list(unique(id))]]


   id ABC Num
1:  1   A 101
2:  1   C 104
3:  1   H 102
4:  3   F 106
5:  3   G 107
6:  3   J 107
7:  5   H 999
8:  5   I 109
9:  6   J  NA

これは、dt2 と dt1 の間で非結合を使用し、これらから一意の ID 値を選択してから、dt2データを適切にサブセット化します。

問題のあるキーの NA 値に関する注意事項があります....

于 2013-02-14T01:12:07.337 に答える
2

ここで@alexwhanの答えが本当に気に入りましたhttps://stackoverflow.com/a/14865931/210673、しかし、多くの列と長い文字列のために結合が遅いように聞こえました。組み合わせごとに一意の番号を数値的に取得する方が速いのではないかと思います。

# get a matrix of unique integers for each column (stacking the two data frames)
ms <- do.call(cbind, lapply(seq_len(ncol(df.t1)), function(ni) {
  xi <- c(as.character(df.t1[[ni]]), as.character(df.t2[[ni]]))
  match(xi, unique(xi))
}))
# convert to base max(ms) to get a single unique identifying number
us <- as.vector(ms %*% max(ms)^c(0:(ncol(ms)-1)))
u2 <- us[(nrow(df.t1)+1):length(us)]
u1 <- us[1:nrow(df.t1)]
# now get changed values and proceed as in alexwhan's answer
ch <- unique(df.t2$id[! u2 %in% u1])
df.t2[df.t2$id %in% ch,]

これは変数を取得するための少し異なる方法usです。少し遅いと思いますが、すべてを浮動小数点数値ではなく整数として保持するように注意する必要があるため、一意性が保証され、浮動小数点オーバーフローが発生すると警告が発生すると思います。ms(それはまだユニークで、すべてがほんの少し小さいので、からも 1 を引きます。)

base <- as.integer(max(ms)^c(0:(nrow(ms)-1)))
us <- apply((ms-1L) * base, 2, sum)
于 2013-02-14T03:30:34.790 に答える
2

これを試して:

df.t1$interact <- with(df.t1, interaction(id, ABC, Num))
df.t2$interact <- with(df.t2, interaction(id, ABC, Num))

change.ids <- unique(df.t2$id[!df.t2$interact %in% df.t1$interact])
new.df <- df.t2[df.t2$id %in% change.ids,]
于 2013-02-14T00:40:05.330 に答える
1

OK、これはいくつかのループを伴う代替手段です。より複雑な例では試していませんが、見てください:

no.change <- vector()
#identifies rows which don't change
for(i in 1:nrow(df.t2)) { 
    for(k in 1:nrow(df.t1)) {
    if(all(df.t2[i,]==df.t1[k,],na.rm=TRUE)) #na.rm gets rid of error
   no.change <- c(no.change, i)
  }
}
# gets ids from all the other rows
id.change <- df.t2$id[-no.change]
df <- df.t2[df.t2$id %in% id.change,]
于 2013-02-14T01:45:12.493 に答える