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

使用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 回答
2

出于效率原因,我建议sample每个组只运行一次。这可以通过以下方式实现:

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了一个只有一个C值的组。检查?sample一下我的意思。

  2. 列的名称将是数字,从 1 到 1000。这可以更改为 @agstudy 的答案。

  3. 行名称也会更改。“修复”它们是相似的,只需使用row.names而不是col.names.

于 2013-06-20T17:40:04.770 回答