我有一个类似下面的数据框。我想在因子级别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,似乎无法找到解决方案。我非常感谢你的帮助。
您已经解决了这个问题 - 您只需要弄清楚如何在多个列中应用它。为此,我建议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
你可以使用permute包。它允许各种排列设计:
require(permute)
CTRL <- how(plots = Plots(strata = df$factor))
apply(df[, 2:4], 2, function(x)
x[shuffle(length(x), control = CTRL)]
)
我使用了apply,因为你想独立地对列进行洗牌。