对具有不同条件的 data.table 行进行采样
sample data.table rows with different conditions
我有一个包含多列的 data.table。这些列之一当前用作 'key'(例如 keyb
)。另一列(假设 A
)中可能有也可能没有数据。我想提供一个向量,每个键随机采样两行,-如果这个键出现在向量中,其中 1 行包含 A
中的数据,而另一行没有。
MRE:
#data.table
trys <- structure(list(keyb = c("x", "x", "x", "x", "x", "y", "y", "y",
"y", "y"), A = c("1", "", "1", "", "", "1", "", "", "1", "")), .Names = c("keyb",
"A"), row.names = c(NA, -10L), class = c("data.table", "data.frame"
))
setkey(trys,keyb)
#list with keys
list_try <- structure(list(a = "x", b = c("r", "y","x")), .Names = c("a", "b"))
例如,我可以根据出现在 list_try
:
中的元素对 data.table
进行子集化
trys[keyb %in% list_try[[2]]]
我最初的(可能是低效的想法)是尝试链接每个键两行的样本,其中 A
列有数据或没有数据,然后合并。但它不起作用:
#here I was trying to sample rows based on whether A has data or not
#here for rows where A has no data
trys[keyb %in% list_try[[2]]][nchar(A)==0][sample(.N, 2), ,by = keyb]
#here for rows where A has data
trys[keyb %in% list_try[[2]]][nchar(A)==1][sample(.N, 2), ,by = keyb]
在这种情况下,我的预期输出将是两个 data.table(一个用于 a
,一个用于 list_try
中的 b
),每次出现两行元素:因此来自 a
的 data.table 将有两行(A 中有数据和没有数据),来自 b
的有四行(A 中有两行有数据,两行没有数据).
如果我能让这个post更清楚,请告诉我
您也可以将 A
添加到 by
语句中,同时通过修改为 A != ""
将其转换为二进制向量,并结合二进制连接(同时添加 nomatch = 0L
以便删除不匹配项)然后您可以通过这两个聚合器从行索引 .I
中采样,然后从原始数据集
中提取子集
对于单个子集案例
trys[trys[list_try[[2]], nomatch = 0L, sample(.I, 1L), by = .(keyb, A != "")]$V1]
# keyb A
# 1: y 1
# 2: y
# 3: x 1
# 4: x
对于更一般的情况,当您想根据键列表创建单独的数据集时,您可以轻松地将其嵌入 lapply
lapply(list_try,
function(x) trys[trys[x, nomatch = 0L, sample(.I, 1L), by = .(keyb, A != "")]$V1])
# $a
# keyb A
# 1: x 1
# 2: x
#
# $b
# keyb A
# 1: y 1
# 2: y
# 3: x 1
# 4: x
我有一个包含多列的 data.table。这些列之一当前用作 'key'(例如 keyb
)。另一列(假设 A
)中可能有也可能没有数据。我想提供一个向量,每个键随机采样两行,-如果这个键出现在向量中,其中 1 行包含 A
中的数据,而另一行没有。
MRE:
#data.table
trys <- structure(list(keyb = c("x", "x", "x", "x", "x", "y", "y", "y",
"y", "y"), A = c("1", "", "1", "", "", "1", "", "", "1", "")), .Names = c("keyb",
"A"), row.names = c(NA, -10L), class = c("data.table", "data.frame"
))
setkey(trys,keyb)
#list with keys
list_try <- structure(list(a = "x", b = c("r", "y","x")), .Names = c("a", "b"))
例如,我可以根据出现在 list_try
:
data.table
进行子集化
trys[keyb %in% list_try[[2]]]
我最初的(可能是低效的想法)是尝试链接每个键两行的样本,其中 A
列有数据或没有数据,然后合并。但它不起作用:
#here I was trying to sample rows based on whether A has data or not
#here for rows where A has no data
trys[keyb %in% list_try[[2]]][nchar(A)==0][sample(.N, 2), ,by = keyb]
#here for rows where A has data
trys[keyb %in% list_try[[2]]][nchar(A)==1][sample(.N, 2), ,by = keyb]
在这种情况下,我的预期输出将是两个 data.table(一个用于 a
,一个用于 list_try
中的 b
),每次出现两行元素:因此来自 a
的 data.table 将有两行(A 中有数据和没有数据),来自 b
的有四行(A 中有两行有数据,两行没有数据).
如果我能让这个post更清楚,请告诉我
您也可以将 A
添加到 by
语句中,同时通过修改为 A != ""
将其转换为二进制向量,并结合二进制连接(同时添加 nomatch = 0L
以便删除不匹配项)然后您可以通过这两个聚合器从行索引 .I
中采样,然后从原始数据集
对于单个子集案例
trys[trys[list_try[[2]], nomatch = 0L, sample(.I, 1L), by = .(keyb, A != "")]$V1]
# keyb A
# 1: y 1
# 2: y
# 3: x 1
# 4: x
对于更一般的情况,当您想根据键列表创建单独的数据集时,您可以轻松地将其嵌入 lapply
lapply(list_try,
function(x) trys[trys[x, nomatch = 0L, sample(.I, 1L), by = .(keyb, A != "")]$V1])
# $a
# keyb A
# 1: x 1
# 2: x
#
# $b
# keyb A
# 1: y 1
# 2: y
# 3: x 1
# 4: x