保持x行数具有相同的值

时间:2016-03-22 18:48:42

标签: r

我想保留包含特定值的行样本,每个值限制为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

关于如何实现这一目标的任何想法?

2 个答案:

答案 0 :(得分:0)

以下是一个基础R解决方案,split根据X2分组,mapplysample应用于不同的群组,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"]