R 基于行数较少的级别,每个级别的子集n行
假设我有一些具有一定级别数的数据帧:R 基于行数较少的级别,每个级别的子集n行,r,R,假设我有一些具有一定级别数的数据帧: x1 x2 ... xi Level 1 1 1 1 A 2 2 2 4 A 3 1 4 2 B . . . . B . . . . B . . . . C . . .
x1 x2 ... xi Level
1 1 1 1 A
2 2 2 4 A
3 1 4 2 B
. . . . B
. . . . B
. . . . C
. . . . C
. . . . C
我试图以一种所有级别都有n行的方式对数据帧进行子集划分,其中n是具有较少实例的级别的行数。在上面的示例中,A是填充较少的级别(2行),因此所需的输出为:
x1 x2 ... xi Level
1 1 1 1 A
2 2 2 4 A
3 1 4 2 B
. . . . B
. . . . C
. . . . C
级别和行数是可变的,因此每次都需要检查行数较少的级别。此外,需要以(伪)随机方式选择每个级别的n行,例如,如果我有:
x1 x2 ... xi Level
1 1 1 1 A
. . . . .
. . . . .
. . . . .
10 1 2 3 C
11 3 2 1 C
12 2 1 3 C
13 3 1 2 C
14 2 3 1 C
n=3时,我希望避免选择级别C(10,11,12)的前3行。
提前感谢。这里有一个
dplyr
解决方案:
library(dplyr)
df %>% group_by(Level) %>% ## group by level
mutate(count = n()) %>% ## count number of rows for each group
ungroup() %>%
mutate(count = min(count)) %>% ## select the minimal number of rows
group_by(Level) %>% ## group again to get X rows for each group
slice(sample(1:n(), min(count))) %>% ## get the X random rows
ungroup() %>%
select(-count) ## remove the added count variable
下面是一个
dplyr
解决方案:
library(dplyr)
df %>% group_by(Level) %>% ## group by level
mutate(count = n()) %>% ## count number of rows for each group
ungroup() %>%
mutate(count = min(count)) %>% ## select the minimal number of rows
group_by(Level) %>% ## group again to get X rows for each group
slice(sample(1:n(), min(count))) %>% ## get the X random rows
ungroup() %>%
select(-count) ## remove the added count variable
以下解决方案仅使用基本R
n <- min(tapply(Level, Level, length))
inx <- unlist(tapply(seq_along(Level), Level, FUN = function(x) sample(x, n)))
dat[inx, ]
# x Level
#2 0.414641434 A
#3 -1.539950042 A
#5 -0.294720447 B
#6 -0.005767173 B
#9 -0.799009249 C
#8 0.763593461 C
#14 0.252223448 D
#11 -0.289461574 D
#16 0.435683299 E
#17 -1.237538422 E
n以下解决方案仅使用基本R
n <- min(tapply(Level, Level, length))
inx <- unlist(tapply(seq_along(Level), Level, FUN = function(x) sample(x, n)))
dat[inx, ]
# x Level
#2 0.414641434 A
#3 -1.539950042 A
#5 -0.294720447 B
#6 -0.005767173 B
#9 -0.799009249 C
#8 0.763593461 C
#14 0.252223448 D
#11 -0.289461574 D
#16 0.435683299 E
#17 -1.237538422 E
nAdplyr
采用sample\u frac
方法进行随机化:
library(dplyr)
df %>%
add_count(Level) %>%
mutate(
n = min(n)
) %>%
group_by(Level) %>%
sample_frac(1) %>%
slice(1:n) %>%
select(-n)
采用dplyr
方法和sample\u frac
进行随机化:
library(dplyr)
df %>%
add_count(Level) %>%
mutate(
n = min(n)
) %>%
group_by(Level) %>%
sample_frac(1) %>%
slice(1:n) %>%
select(-n)
数据表
解决方案dat[,.N,Level]
给出每个级别组的行数,然后min(N)
即minN
是最小的行数。下一行从每组中获取顶部的minN
行
library(data.table)
setDT(dat)
minN <- dat[, .N, Level][, min(N)]
dat[, head(.SD, minN), Level]
# Level x
# 1: A 1.2724293
# 2: A 0.4146414
# 3: B -0.9285670
# 4: B -0.2947204
# 5: C 2.4046534
# 6: C 0.7635935
# 7: D -0.2894616
# 8: D -0.2992151
# 9: E 0.4356833
# 10: E -1.2375384
或者使用arg0naut评论中的解决方案
dat[, .SD[sample(.N, minN)], by = Level]
如果你愿意牺牲一些可读性来提高速度,另一个选择是
dat[dat[, sample(.I, minN), Level]$V1]
使用的数据(来自Rui Barradas的回答)
set.seed(1)
s数据。表
解决方案dat[,.N,Level]
给出每个级别组的行数,然后min(N)
即minN
是最小的行数。下一行从每组中获取顶部的minN
行
library(data.table)
setDT(dat)
minN <- dat[, .N, Level][, min(N)]
dat[, head(.SD, minN), Level]
# Level x
# 1: A 1.2724293
# 2: A 0.4146414
# 3: B -0.9285670
# 4: B -0.2947204
# 5: C 2.4046534
# 6: C 0.7635935
# 7: D -0.2894616
# 8: D -0.2992151
# 9: E 0.4356833
# 10: E -1.2375384
或者使用arg0naut评论中的解决方案
dat[, .SD[sample(.N, minN)], by = Level]
如果你愿意牺牲一些可读性来提高速度,另一个选择是
dat[dat[, sample(.I, minN), Level]$V1]
使用的数据(来自Rui Barradas的回答)
set.seed(1)
它可以正常工作,但是它会选择每个级别的前n行(它应该以随机方式选择n行),可能是使用“createDataPartition()”?谢谢@Pepv请看下面我的答案,这是一个简洁的版本,带有用于随机化的sample\u frac
。添加了一个sample
。它工作正常,但它选择每个级别的前n行(它应该以随机方式选择n行),可能使用“createDataPartition()”?谢谢@Pepv请看下面我的答案,这是一个简洁的版本,带有用于随机化的sample\u frac
。添加了一个sample
。1
的一小部分就是一切。是的,但它会排列行,以便随后随机切片。否则,只对初始数据集的前两行进行切片。1
的一小部分就是一切。是的,但它会排列这些行,以便随后对它们进行随机切片。否则,只对初始数据集的前两行进行切片。minNminN