2

私はこのデータフレームを持っています:

df <- data.frame(A=c("a","b","c","d","e","f","g","h","i"), 
           B=c("1","1","1","2","2","2","3","3","3"), 
           C=c(0.1,0.2,0.4,0.1,0.5,0.7,0.1,0.2,0.5))

> df
  A B   C 
1 a 1 0.1 
2 b 1 0.2 
3 c 1 0.4 
4 d 2 0.1 
5 e 2 0.5 
6 f 2 0.7 
7 g 3 0.1 
8 h 3 0.2 
9 i 3 0.5

さらに 1000 列を追加し、この列に によって生成された値を入力したいと思います。

transform(df, D=ave(C, B, FUN=function(b) sample(b, replace=TRUE)))

forループで試しましたが、うまくいきません:

for (i in 4:1000){
  df[, 4:1000] <- NA
  df[,i] = transform(df, D=ave(C, B, FUN=function(b) sample(b, replace=TRUE)))
  }
4

2 に答える 2

2

sample効率的な理由から、グループごとに 1 回だけ実行することをお勧めします。これはこれで達成できます:

sample2 <- function(x, size)
{
    if(length(x)==1) rep(x, size) else sample(x, size, replace=TRUE)
}


new_df <- do.call(rbind, by(df, df$B,
            function(d) cbind(d, matrix(sample2(d$C, length(d$C)*1000), 
                                        ncol=1000))))

ノート:

  1. sample2値が1つしかないグループがある場合に備えて作成しましたC?sample私が何を意味するかを確認してください。

  2. 列の名前は、1 から 1000 までの数字になります。これは、@agstudy による回答のように変更できます。

  3. 行名も変更されます。それらを「修正」することは似ていますが、row.names代わりにcol.names.

于 2013-06-20T17:40:04.770 に答える
2

replicateたとえば、次のように使用します。

cbind(df,replicate(1000,ave(df$C, df$B, 
           FUN=function(b) sample(b, replace=TRUE))))

たとえば、4 つの列を追加するには、次のようにします。

 cbind(df,replicate(4,ave(df$C, df$B, 
     FUN=function(b) sample(b, replace=TRUE))))

  A B   C   1   2   3   4
1 a 1 0.1 0.2 0.2 0.1 0.2
2 b 1 0.2 0.4 0.2 0.4 0.4
3 c 1 0.4 0.1 0.1 0.1 0.1
4 d 2 0.1 0.1 0.5 0.5 0.1
5 e 2 0.5 0.7 0.1 0.5 0.1
6 f 2 0.7 0.1 0.7 0.7 0.7
7 g 3 0.1 0.2 0.5 0.2 0.2
8 h 3 0.2 0.2 0.1 0.2 0.1
9 i 3 0.5 0.5 0.5 0.1 0.5

たぶん、次のような名前で列の名前を変更する必要があります:

gsub('([0-9]+)','D\\1',colnames(res))
1] "A"  "B"  "C"  "D1" "D2" "D3" "D4"
于 2013-06-20T17:30:29.717 に答える