我想保留包含特定值的行样本,每个值限制为3行。
例如,假设我希望每种颜色最多保留3行:
X1 X2
1 0.7091409 RED
2 -1.1334614 BLUE
3 2.3343391 RED
4 -0.9040278 GREEN
5 0.4180331 RED
6 0.7572246 RED
7 -0.8996483 BLUE
8 -1.0356774 BLUE
9 -0.3983045 GREEN
10 -0.9060305 BLUE
此处,在列X2中,RED出现4次,BLUE出现4次,GREEN出现2次。我想修剪行以保留最多3行,其中包含X2列中的特定值。所以上面的数据集将成为:
X1 X2
1 0.7091409 RED
2 -1.1334614 BLUE
3 2.3343391 RED
4 -0.9040278 GREEN
5 0.4180331 RED
6 -0.8996483 BLUE
7 -1.0356774 BLUE
8 -0.3983045 GREEN
关于如何实现这一目标的任何想法?
答案 0 :(得分:0)
以下是一个基础R解决方案,split
根据X2
分组,mapply
将sample
应用于不同的群组,pmin
获取每组的样本量。
d2 <- split(d$X1, d$X2)
stack(mapply(sample, d2, pmin(lengths(d2), 3)))
另一种解决方案可能是使用stratified
包中的splitstackshape
:
library(splitstackshape)
stratified(d, "X2", size = pmin(lengths(split(d$X1, d$X2)), 3))
当样本中包含多于两列时,此解决方案有效。
使用上面的基础R答案处理两列以上。如果X1
中的所有值都是唯一的,您只需将采样数据与原始数据合并(左连接)即可填写:
sampled_d <- stack(mapply(sample, d2, pmin(lengths(d2), 3))) # same as base solution above
merge(sampled_d, d,
by.x = c("values", "ind"),
by.y = c("X1", "X2"),
all.x = TRUE) # left join
否则,基本解决方案可以适应以下丑陋的代码:
d3 <- split(d, d$X2)
do.call(rbind,
mapply(function(ii, jj) ii[sample(nrow(ii), jj), ],
d3,
pmin(lapply(d3, function(ii) dim(ii)[1]), 3),
SIMPLIFY = FALSE))
示例数据:
d <- read.table(text="
X1 X2
1 0.7091409 RED
2 -1.1334614 BLUE
3 2.3343391 RED
4 -0.9040278 GREEN
5 0.4180331 RED
6 0.7572246 RED
7 -0.8996483 BLUE
8 -1.0356774 BLUE
9 -0.3983045 GREEN
10 -0.9060305 BLUE", header=TRUE)
答案 1 :(得分:0)
我相信this solution为我工作。
# install.package(data.table) # if necessary
library(data.table)
# convert my dataframe (df2) to a datatable
DT <- data.table(df2)
然后,执行为由“X2”列中的值定义的组保留最多3行的函数。
DT2 <- DT[, head(.SD, 3), by = "X2"]