根据条件从辅助数据表采样到主数据表
Sampling from a secondary datatable to the main datatable based on a condition
我有两个数据表 dt_main
和 dt_unit
。
set.seed(1)
dt_main<-data.table(ID=sample(1:20,size=10),Group=sample(1:3,size=10,replace=TRUE),Unit=0)
dt_unit<-data.table(Group=sample(1:3,size=10,replace=TRUE),Unit_id=sample(1000:3000,size=10,replace=TRUE))
dt_main
看起来像这样:
> dt_main
ID Group Unit
1: 4 1 0
2: 7 1 0
3: 1 1 0
4: 2 2 0
5: 13 2 0
6: 19 2 0
7: 11 2 0
8: 17 3 0
9: 14 1 0
10: 3 3 0
dt_unit
看起来像这样:
> dt_unit
Group Unit_id
1: 1 2624
2: 1 2963
3: 1 1974
4: 1 1800
5: 2 1851
6: 1 1930
7: 1 1325
8: 2 1329
9: 2 1553
10: 2 2445
我想用相同的 [=24] 从 dt_unit
到 dt_main
抽取一个 Unit_id
来填充 dt_main
中的 Unit
列=].
例如,对于 dt_main
中的第一行(因此 Group
=1),代码应查找 dt_unit
并找到 Group
为 1 的行(见下文)和 select 一个 Unit_id
并将其插入 Unit
.
> dt_unit[Group==1]
Group Unit_id
1: 1 2624
2: 1 2963
3: 1 1974
4: 1 1800
5: 1 1930
6: 1 1325
我试过这样的方法,它为每一行分配了相同的数字:
dt_main[,Unit:=sample(dt_unit[Group==Group]$Unit_id,size=1)]
我也试过sapply
但没用。
这是一个基本的 R 解决方案,我们每次都匹配组和样本 1 值,
dt_main$Unit <- sapply(dt_main$Group, function(i) {
v1 <- dt_unit$Unit_id[dt_unit$Group %in% i];
if (length(v1) > 0) {sample(v1, 1) } else {NA}
})
# ID Group Unit
# 1: 4 1 1930
# 2: 7 1 1325
# 3: 1 1 1325
# 4: 2 2 1329
# 5: 13 2 2445
# 6: 19 2 2445
# 7: 11 2 1851
# 8: 17 3 NA
# 9: 14 1 1930
#10: 3 3 NA
您可以通过 Group
和 select 加入 dt_main
和 dt_unit
每个 ID
的随机行。
使用 dplyr
,您可以通过以下方式完成此操作:
library(dplyr)
left_join(dt_main, dt_unit, by = 'Group') %>% group_by(ID) %>% sample_n(1)
# ID Group Unit_id
# <int> <int> <int>
# 1 1 1 1800
# 2 2 2 2445
# 3 3 3 NA
# 4 4 1 2963
# 5 7 1 1800
# 6 11 2 1851
# 7 13 2 1553
# 8 14 1 1325
# 9 17 3 NA
#10 19 2 2445
我从 data.table
创建中删除了 Unit
列。
另一个答案mapply
,我用它来处理有多个条件的情况。在这种情况下,在查找时我会检查 Group
列是否匹配并且 dt_main 中的新列 (Size
) 是否大于 dt_unit
中的新列。作为 OP,我必须向原始 post 添加另一个条件,因此添加此解决方案以帮助未来的用户。
my_fun<-function(var1,var2)
{
d<-dt_unit[(Group%in%var1)&(Size>=var2)]
if(nrow(d)>=2){
sample(x=d$Unit_id,size=1,replace=T)
}else
{d$Unit_id}
}
vars1<-dt_main$Group
vars2<-dt_main$Size
dt_main$Unit<-mapply(my_fun,vars1,vars2)
我有两个数据表 dt_main
和 dt_unit
。
set.seed(1)
dt_main<-data.table(ID=sample(1:20,size=10),Group=sample(1:3,size=10,replace=TRUE),Unit=0)
dt_unit<-data.table(Group=sample(1:3,size=10,replace=TRUE),Unit_id=sample(1000:3000,size=10,replace=TRUE))
dt_main
看起来像这样:
> dt_main
ID Group Unit
1: 4 1 0
2: 7 1 0
3: 1 1 0
4: 2 2 0
5: 13 2 0
6: 19 2 0
7: 11 2 0
8: 17 3 0
9: 14 1 0
10: 3 3 0
dt_unit
看起来像这样:
> dt_unit
Group Unit_id
1: 1 2624
2: 1 2963
3: 1 1974
4: 1 1800
5: 2 1851
6: 1 1930
7: 1 1325
8: 2 1329
9: 2 1553
10: 2 2445
我想用相同的 [=24] 从 dt_unit
到 dt_main
抽取一个 Unit_id
来填充 dt_main
中的 Unit
列=].
例如,对于 dt_main
中的第一行(因此 Group
=1),代码应查找 dt_unit
并找到 Group
为 1 的行(见下文)和 select 一个 Unit_id
并将其插入 Unit
.
> dt_unit[Group==1]
Group Unit_id
1: 1 2624
2: 1 2963
3: 1 1974
4: 1 1800
5: 1 1930
6: 1 1325
我试过这样的方法,它为每一行分配了相同的数字:
dt_main[,Unit:=sample(dt_unit[Group==Group]$Unit_id,size=1)]
我也试过sapply
但没用。
这是一个基本的 R 解决方案,我们每次都匹配组和样本 1 值,
dt_main$Unit <- sapply(dt_main$Group, function(i) {
v1 <- dt_unit$Unit_id[dt_unit$Group %in% i];
if (length(v1) > 0) {sample(v1, 1) } else {NA}
})
# ID Group Unit
# 1: 4 1 1930
# 2: 7 1 1325
# 3: 1 1 1325
# 4: 2 2 1329
# 5: 13 2 2445
# 6: 19 2 2445
# 7: 11 2 1851
# 8: 17 3 NA
# 9: 14 1 1930
#10: 3 3 NA
您可以通过 Group
和 select 加入 dt_main
和 dt_unit
每个 ID
的随机行。
使用 dplyr
,您可以通过以下方式完成此操作:
library(dplyr)
left_join(dt_main, dt_unit, by = 'Group') %>% group_by(ID) %>% sample_n(1)
# ID Group Unit_id
# <int> <int> <int>
# 1 1 1 1800
# 2 2 2 2445
# 3 3 3 NA
# 4 4 1 2963
# 5 7 1 1800
# 6 11 2 1851
# 7 13 2 1553
# 8 14 1 1325
# 9 17 3 NA
#10 19 2 2445
我从 data.table
创建中删除了 Unit
列。
另一个答案mapply
,我用它来处理有多个条件的情况。在这种情况下,在查找时我会检查 Group
列是否匹配并且 dt_main 中的新列 (Size
) 是否大于 dt_unit
中的新列。作为 OP,我必须向原始 post 添加另一个条件,因此添加此解决方案以帮助未来的用户。
my_fun<-function(var1,var2)
{
d<-dt_unit[(Group%in%var1)&(Size>=var2)]
if(nrow(d)>=2){
sample(x=d$Unit_id,size=1,replace=T)
}else
{d$Unit_id}
}
vars1<-dt_main$Group
vars2<-dt_main$Size
dt_main$Unit<-mapply(my_fun,vars1,vars2)