3

まず第一に、質問のタイトルが不明瞭であることに謝罪します。それは、私が一行でどのように表現するかを知らなかった非常に具体的な質問です!

とにかく、私の問題は次のとおりです。ID、親ID、および2つの値(たとえばaとb)を持つデータフレームがあります。行のIDを、その値がそのparent_idと等しくない場合を除いて、そのparent_idに更新したいと思います。

たとえば、テーブルがあるとします。

id parent_id a b  
1    0       x x
2    1       x x
3    1       x y
4    0       y y
5    4       x x 
6    1       x x
7    4       y y

これはコードで生成できます

 x <- data.frame('id' = c(1,2,3,4,5,6,7),
                 'parent_id' = c(0,1,1,0,4,1,4),
                 'a' = c('x','x','x','y','x','x','y'),
                 'b' = c('x','x','y','y','x','x','y'))

これは次のようになります。

id parent_id a b
1    0       x x
1    1       x x
3    1       x y
4    0       y y
5    4       x x
1    1       x x
4    4       y y

したがって、id2は1になりparent_id、それはプロパティであり、両方ともに等しく、 1aと同じですが、3は同じままですが、同じプロパティを持っていません。bxididparent_id1

どんな助けでもいただければ幸いです。

4

4 に答える 4

1

この更新されたバージョンは、テキストまたは数値ID変数で機能するはずです。

vars <- c("a","b")
matches <- apply(x[vars]==x[match(x$parent_id,x$id),][vars],1,all)
x$id[matches==TRUE & is.na(matches)==FALSE] <- x$parent_id[matches==TRUE & is.na(matches)==FALSE]
于 2012-06-20T22:36:08.910 に答える
1

お二人のおかげで、thelatemails の回答は私が提供した例では機能しますが、実際には私のデータフレームの ID は 1、2、3、4 などではありません...しかし、よりランダムですべての数字が含まれていないため、コードds[matches, ] になると落ちます。mplourde answer はトリックを行っていたと思いますが、次のコードを使用して終了しました。

  betValues <- with(x, paste(id, a, b, sep="-"))

  x[, 'id'] <- with(x, ifelse(parent_id== 0, id, 
          ifelse(!paste(parent_id, a, b, sep="-") %in%  betValues, id, parent_id)))

これは機能し、かなり迅速できちんとしていると思います。

ありがとう

于 2012-06-21T10:33:49.037 に答える
1

他の誰かがよりエレガントな解決策を持っているかもしれませんが、これはあなたが望むものを手に入れます:

# list of a-b pairs for parent_id
parent.id.ab <- with(x, lapply(parent_id, FUN=function(y) c(a[id==y], b[id==y])))

# list of a-b pairs for id
id.ab <- with(x, mapply(function(y,z) c(y,z), a, b, SIMPLIFY=FALSE))

# condition is a vector of TRUE/FALSE, TRUE if the parent_id a-b pair equals the id a-b.
# When the parent_id is 0, its a-b pair is integer(0). Since all(logical(0)) is TRUE,
# we only use all(z == y) when z and y have the same length.
condition <- mapply(function(z,y) if (length(z) == length(y)) all(z == y) else FALSE, 
                    parent.id.ab, id.ab)

x$id <- ifelse(condition, x$parent_id, x$id)
于 2012-06-20T19:28:34.137 に答える
0

興味深い問題、私の見解:

own.idx        <- seq_len(nrow(x))
parent.idx     <- match(x$parent_id, x$id)
matches.parent <- mapply(function(i,j)!is.na(j) && all(x[i, c("a", "b")] ==
                                                       x[j, c("a", "b")]),
                         own.idx, parent.idx)

x$id <- ifelse(matches.parent, x$parent_id, x$id)
于 2012-07-08T23:04:00.297 に答える