特定列中的随机/置换值,用于组变量的特定因子级别

时间:2014-08-19 12:29:31

标签: r permutation sample r-factor

我有一个类似下面的数据框。我想将因子级别A1,A2,B1,B2中的V1,V2和V3列的值混淆。

n<-1:10
df <- data.frame(factor = c("A1","A1","A1","A2","A2","A2",
                             "B1","B1","B1","B2","B2","B2"),                     
                vars<-as.data.frame(sapply(1:3,function(i)sample(n,12,replace=T))) )

   factor V1 V2 V3
1      A1  8  1  1
2      A1  7  2  9
3      A1  4  5  2
4      A2  6  5  2
5      A2  8  3  4
6      A2  1  9  3
7      B1  5  6  8
8      B1 10  4  6
9      B1  6  1  9
10     B2  4  6  7
11     B2  7  5  8
12     B2 10  2  7

我希望它看起来像这样:

   factor V1 V2 V3
1      A1  4  1  2
2      A1  8  5  1
3      A1  7  2  9
4      A2  8  9  2
5      A2  1  3  3
6      A2  6  5  4
7      B1  5  4  6
8      B1  6  6  8
9      B1  10 1  9
10     B2  10 6  8
11     B2  4  2  7
12     B2  7  5  7

我希望更改数据框中的列 - 而不是在其上添加列。我尝试过在此页面上找到的不同选项,例如:

require(plyr)
df1<- ddply(df, .(factor),summarize, ans=sample(V1))
or
df2<-transform(df, new.V1=ave(c(V1), factor, FUN=function(b) sample(b)))

两者都可以正常更改一列,但在这两种情况下我都无法一次对多个列进行采样。 df1生成一个新列而不包含旧数据帧的其余部分,df2将采样列附加到旧列上。所以在某种程度上我更喜欢df1,但如果我不能让它同时执行多个列,那么这并没有帮助。必须有一个简单的解决方案,但我已经上下扫描stackoverflow,似乎无法找到解决方案。我非常感谢你的帮助。

2 个答案:

答案 0 :(得分:1)

您已经解决了这个问题 - 您只需要弄清楚如何在多个列中应用它。为此,我建议lapply,就像这样......

首先,您的样本数据(但可重现,set.seed

set.seed(1)
n <- 1:10
df <- data.frame(factor = c("A1","A1","A1","A2","A2","A2",
                            "B1","B1","B1","B2","B2","B2"),
                 vars <- as.data.frame(
                   sapply(1:3, function(i) 
                     sample(n, 12, replace = T))))
df
#    factor V1 V2 V3
# 1      A1  3  7  3
# 2      A1  4  4  4
# 3      A1  6  8  1
# 4      A2 10  5  4
# 5      A2  3  8  9
# 6      A2  9 10  4
# 7      B1 10  4  5
# 8      B1  7  8  6
# 9      B1  7 10  5
# 10     B2  1  3  2
# 11     B2  3  7  9
# 12     B2  2  2  7

我们会处理副本,而不是直接修改原始数据。

df_copy <- df ## Because the next step is destructive

df_copy[-1] <- lapply(df_copy[-1], function(x) {
  ave(x, df_copy[[1]], FUN = sample)
})
df_copy
#    factor V1 V2 V3
# 1      A1  6  8  1
# 2      A1  3  4  3
# 3      A1  4  7  4
# 4      A2  3 10  4
# 5      A2  9  5  9
# 6      A2 10  8  4
# 7      B1  7  4  6
# 8      B1  7 10  5
# 9      B1 10  8  5
# 10     B2  2  7  7
# 11     B2  1  2  2
# 12     B2  3  3  9

答案 1 :(得分:0)

你可以使用permute包。它允许各种排列设计:

require(permute)
CTRL <- how(plots = Plots(strata = df$factor))
apply(df[, 2:4], 2, function(x)
  x[shuffle(length(x), control = CTRL)]
  )

我使用了apply,因为你想独立地对列进行洗牌。