7

私の質問は、いくつかの因子変数を持つデータフレームがあります。ここで、このデータフレームに新しいベクトルを割り当てます。これにより、これらの因子変数のサブセットごとにインデックスが作成されます。

   data <-data.frame(fac1=factor(rep(1:2,5)), fac2=sample(letters[1:3],10,rep=T))

私に次のようなものを与えます:

        fac1 fac2
     1     1    a
     2     2    c
     3     1    b
     4     2    a
     5     1    c
     6     2    b
     7     1    a
     8     2    a
     9     1    b
     10    2    c

そして、私が欲しいのは、各因子の組み合わせの発生をカウントする組み合わせカウンターです。このような

        fac1 fac2  counter
     1     1    a        1
     2     2    c        1
     3     1    b        1
     4     2    a        1
     5     1    c        1
     6     2    b        1
     7     1    a        2
     8     2    a        2
     9     1    b        2
     10    1    a        3

これまでのところ、tapplyを使用して、すべての因子の組み合わせに対してカウンターを取得することを考えました。これは正常に機能します。

counter <-tapply(data$fac1, list(data$fac1,data$fac2), function(x) 1:length(x))

しかし、非効率的なループを使用せずに、データフレーム内の組み合わせにカウンターリスト(リストされていないなど)を割り当てる方法がわかりません:)

4

4 に答える 4

6

これはave()関数の仕事です:

# Use set.seed for reproducible examples 
#   when random number generation is involved
set.seed(1) 
myDF <- data.frame(fac1 = factor(rep(1:2, 7)), 
                   fac2 = sample(letters[1:3], 14, replace = TRUE), 
                   stringsAsFactors=FALSE)
myDF$counter <- ave(myDF$fac2, myDF$fac1, myDF$fac2, FUN = seq_along)
myDF
#    fac1 fac2 counter
# 1     1    a       1
# 2     2    b       1
# 3     1    b       1
# 4     2    c       1
# 5     1    a       2
# 6     2    c       2
# 7     1    c       1
# 8     2    b       2
# 9     1    b       2
# 10    2    a       1
# 11    1    a       3
# 12    2    a       2
# 13    1    c       2
# 14    2    b       3

stringsAsFactors=FALSE手順でのの使用に注意してくださいdata.frame()。それがなかった場合でも、次のコマンドで出力を取得できますmyDF$counter <- ave(as.character(myDF$fac2), myDF$fac1, myDF$fac2, FUN = seq_along)

于 2012-10-25T15:53:11.283 に答える
4

data.tableソリューション

library(data.table)
DT <- data.table(data)
DT[, counter := seq_len(.N), by = list(fac1, fac2)]
于 2012-10-25T22:35:28.510 に答える
0

これは、(明示的な)ループを回避するベースRの方法です。

data$counter <- with(data, {
    inter <- as.character(interaction(fac1, fac2))
    names(inter) <- seq_along(inter)
    inter.ordered <- inter[order(inter)]
    counter <- with(rle(inter.ordered), unlist(sapply(lengths, sequence)))
    counter[match(names(inter), names(inter.ordered))]
})
于 2012-10-25T15:42:01.940 に答える
0

ここに少しループのあるバリアントがあります(「data」が別の方法で使用されているため、変数の名前を「x」に変更しました)。

x <-data.frame(fac1=rep(1:2,5), fac2=sample(letters[1:3],10,rep=T))
x$fac3 <- paste( x$fac1, x$fac2, sep="" )
x$ctr <- 1
y <- table( x$fac3 )
for( i in 1 : length( rownames( y ) ) )
  x$ctr[x$fac3 == rownames(y)[i]] <- 1:length( x$ctr[x$fac3 == rownames(y)[i]] )
x <- x[-3]

これが大きなdata.frameで効率的かどうかはわかりませんが、機能します。

于 2012-10-25T15:57:21.920 に答える