选择一个因素内的因素水平
Selection of levels of factors within a factor
这是我的例子:
df<-data.frame(ID=as.factor(c(rep("A",20),rep("B",15))),var=as.factor(c(rep("w",5),rep("x",10),rep("y",12),rep("z",8))), obs=runif(35,0,10))
我想做的是,对于每个 'ID',能够 select 一个 'var',随机并且可能 selecting 'var' 最多 'obs'。因此,例如,它可以随机给出:
ID var obs
6 A x 3.44405412
7 A x 1.50957637
8 A x 8.22009420
9 A x 7.47094473
10 A x 8.26098410
11 A x 9.62919537
12 A x 0.10393890
13 A x 0.11298502
14 A x 4.33822574
15 A x 4.20109035
28 B z 1.07697286
29 B z 8.40864310
30 B z 7.62563257
31 B z 0.06885177
32 B z 4.33959316
33 B z 7.98303782
34 B z 8.38335593
35 B z 4.52110318
预先感谢您的帮助。
一个选项使用 data.table
。
我们将 'data.frame' 转换为 'data.table' (setDT(df)
)。按 'ID' 和 'var' 分组,我们创建一个变量 'N',它给出每个组的行数 (.N
)。然后,我们按 'ID' 分组,并对具有 'N' (.SD[N==max(N)]
) 的 max
值的行进行子集化。 'N' 列可以分配给 'NULL',因为它在预期输出中不需要。
library(data.table)
setDT(df)[,N := .N , by = .(ID, var)][, .SD[N==max(N)] ,
by = .(ID)][, N:= NULL][]
# ID var obs
# 1: A x 9.2044378
# 2: A x 2.7973557
# 3: A x 7.6382046
# 4: A x 8.0163062
# 5: A x 2.5472509
# 6: A x 6.0488886
# 7: A x 3.7073495
# 8: A x 6.7169025
# 9: A x 6.7298231
#10: A x 3.2043056
#11: B z 5.9973018
#12: B z 6.3014766
#13: B z 0.4663503
#14: B z 3.1951313
#15: B z 2.3874890
#16: B z 3.6881753
#17: B z 1.4802475
#18: B z 9.3776173
通过分配新列,我们正在更改原始数据集 'df'。我们稍后可以通过
从原始数据集中删除该列
df[, N:=NULL]
或者在不分配 (:=
) 的情况下修改上述代码,以便原始数据集保持不变。我们连接 .SD
即 Subset of Datatable
与 .N
以创建新列 'N',然后像以前一样对行进行子集化。
setDT(df)[, c(list(N=.N), .SD) ,by =.(ID, var)][,
.SD[N==max(N)], by =ID][, N:= NULL][]
或者按照@Frank 的建议,我们可以 copy(.SD)
避免原始数据集被更改,然后分配 'N',然后像以前一样做。
setDT(df)[,copy(.SD)][,N := .N , by = .(ID, var)][,
.SD[N==max(N)] , by = .(ID)][]
如果我们想select在每个'ID'内随机'var',我们可以使用sample
来select单个'var'分组通过 'ID',得到一个逻辑向量 (var==sample(var, 1)]
) 并对行
进行子集化
setDT(df)[, .SD[var==sample(var, 1)] , by =ID]
数据
set.seed(24)
df <- data.frame(ID=as.factor(c(rep("A",20),rep("B",15))),
var=as.factor(c(rep("w",5),rep("x",10),rep("y",12),rep("z",8))),
obs=runif(35,0,10))
这是另一种 data.table 方法。开始...
library(data.table)
setDT(df)
然后,select var
每个 ID
:
# var with highest #obs
idvar_selected = df[,.(var = .SD[,.N,by=var][which.max(N)]$var), by=ID]
# or... at random, weighted by #obs
idvar_selected = df[,.(var = sample(var,1)), by=ID]
和"join"使用select离子:
df[idvar_selected, on=c("ID","var")]
这是我的例子:
df<-data.frame(ID=as.factor(c(rep("A",20),rep("B",15))),var=as.factor(c(rep("w",5),rep("x",10),rep("y",12),rep("z",8))), obs=runif(35,0,10))
我想做的是,对于每个 'ID',能够 select 一个 'var',随机并且可能 selecting 'var' 最多 'obs'。因此,例如,它可以随机给出:
ID var obs
6 A x 3.44405412
7 A x 1.50957637
8 A x 8.22009420
9 A x 7.47094473
10 A x 8.26098410
11 A x 9.62919537
12 A x 0.10393890
13 A x 0.11298502
14 A x 4.33822574
15 A x 4.20109035
28 B z 1.07697286
29 B z 8.40864310
30 B z 7.62563257
31 B z 0.06885177
32 B z 4.33959316
33 B z 7.98303782
34 B z 8.38335593
35 B z 4.52110318
预先感谢您的帮助。
一个选项使用 data.table
。
我们将 'data.frame' 转换为 'data.table' (setDT(df)
)。按 'ID' 和 'var' 分组,我们创建一个变量 'N',它给出每个组的行数 (.N
)。然后,我们按 'ID' 分组,并对具有 'N' (.SD[N==max(N)]
) 的 max
值的行进行子集化。 'N' 列可以分配给 'NULL',因为它在预期输出中不需要。
library(data.table)
setDT(df)[,N := .N , by = .(ID, var)][, .SD[N==max(N)] ,
by = .(ID)][, N:= NULL][]
# ID var obs
# 1: A x 9.2044378
# 2: A x 2.7973557
# 3: A x 7.6382046
# 4: A x 8.0163062
# 5: A x 2.5472509
# 6: A x 6.0488886
# 7: A x 3.7073495
# 8: A x 6.7169025
# 9: A x 6.7298231
#10: A x 3.2043056
#11: B z 5.9973018
#12: B z 6.3014766
#13: B z 0.4663503
#14: B z 3.1951313
#15: B z 2.3874890
#16: B z 3.6881753
#17: B z 1.4802475
#18: B z 9.3776173
通过分配新列,我们正在更改原始数据集 'df'。我们稍后可以通过
从原始数据集中删除该列df[, N:=NULL]
或者在不分配 (:=
) 的情况下修改上述代码,以便原始数据集保持不变。我们连接 .SD
即 Subset of Datatable
与 .N
以创建新列 'N',然后像以前一样对行进行子集化。
setDT(df)[, c(list(N=.N), .SD) ,by =.(ID, var)][,
.SD[N==max(N)], by =ID][, N:= NULL][]
或者按照@Frank 的建议,我们可以 copy(.SD)
避免原始数据集被更改,然后分配 'N',然后像以前一样做。
setDT(df)[,copy(.SD)][,N := .N , by = .(ID, var)][,
.SD[N==max(N)] , by = .(ID)][]
如果我们想select在每个'ID'内随机'var',我们可以使用sample
来select单个'var'分组通过 'ID',得到一个逻辑向量 (var==sample(var, 1)]
) 并对行
setDT(df)[, .SD[var==sample(var, 1)] , by =ID]
数据
set.seed(24)
df <- data.frame(ID=as.factor(c(rep("A",20),rep("B",15))),
var=as.factor(c(rep("w",5),rep("x",10),rep("y",12),rep("z",8))),
obs=runif(35,0,10))
这是另一种 data.table 方法。开始...
library(data.table)
setDT(df)
然后,select var
每个 ID
:
# var with highest #obs
idvar_selected = df[,.(var = .SD[,.N,by=var][which.max(N)]$var), by=ID]
# or... at random, weighted by #obs
idvar_selected = df[,.(var = sample(var,1)), by=ID]
和"join"使用select离子:
df[idvar_selected, on=c("ID","var")]