在数据框中创建列,按因子级别从另一列中采样
Posted
技术标签:
【中文标题】在数据框中创建列,按因子级别从另一列中采样【英文标题】:Create column in dataframe that samples from another column by factor levels 【发布时间】:2014-04-22 19:03:55 【问题描述】:我希望我的数据框dat
的列x3
包含x2
列的随机样本,但随机样本应该只来自x1
列中给出的相同因子水平。我研究了函数by()
、ddply()
和sample()
,但似乎无法使其工作。我还检查了similar question,但它对我没有帮助。您可以在下面的可重现示例的上下文中看到我尝试的(我希望是)。
这是示例数据框:
dat <- data.frame(x1=c("a","a","a","b","b","b","c","c","c"),x2=1:9);
dat$x1 <- as.factor(dat$x1);
dat;
x1 x2
1 a 1
2 a 2
3 a 3
4 b 4
5 b 5
6 b 6
7 c 7
8 c 8
9 c 9
然后我生成 x3 的一些非工作尝试如下:
set.seed(99);
by(dat,FUN=dat$x1,dat$x3<-sample(dat$x1,1,replace=FALSE)); #this did not work at all
我也试过了
set.seed(99);
a <- by(dat,dat[,"x1"],function(d)sample(d$x2,3,replace=FALSE),simplify=TRUE);
dat$x3<-a;
a;
dat[, "x1"]: a
[1] 2 1 3
---------------------------------------------------------------------------------------------------
dat[, "x1"]: b
[1] 6 5 4
---------------------------------------------------------------------------------------------------
dat[, "x1"]: c
[1] 9 7 8
dat;
> dat
x1 x2 x3
1 a 1 2, 1, 3
2 a 2 6, 5, 4
3 a 3 9, 7, 8
4 b 4 2, 1, 3
5 b 5 6, 5, 4
6 b 6 9, 7, 8
7 c 7 2, 1, 3
8 c 8 6, 5, 4
9 c 9 9, 7, 8
我在a
中找到了我需要的东西,因为存在按因子水平的随机重采样,但a
不是一个简单的向量。我觉得如果a
是一个向量,我将拥有我需要的东西,因为我可以将它分配给dat$x3
。总而言之,我希望 dat 变成这样:
dat
x1 x2 x3
1 a 1 2
2 a 2 1
3 a 3 3
4 b 4 6
5 b 5 5
6 b 6 4
7 c 7 9
8 c 8 7
9 c 9 8
该解决方案对于具有 >200 万行的数据框应该是有效的。感谢任何人的帮助。我希望在我使用 r 变得更好时将帮助回馈给其他人。
【问题讨论】:
用 plyr 这样的东西应该可以工作:dat <- ddply(dat, .(x1), transform, x3=sample(x2))
或使用基函数:dat$x3 <- do.call(c, tapply(dat$x2, dat$x1, sample))
@beetroot - 这行得通;其他几个人提供的选项也是如此。这有助于弄清楚 ddply。
@Roland - 这很有效,帮助我理解了tapply
【参考方案1】:
dat$x3 <- ave( dat$x2, dat$x1, FUN=sample)
您构建输出的方式(具有与数据帧的行数相同的条目数)您将在 x1 的不同值中获得 x2 值的排列。 (编辑您的代码以使其运行。)
【讨论】:
这行得通。对于这样的任务,似乎有很多选择以上是关于在数据框中创建列,按因子级别从另一列中采样的主要内容,如果未能解决你的问题,请参考以下文章