选择因子内的因子水平

时间:2015-08-04 20:23:46

标签: r dataframe factors

这是我的例子:

nbproject/private/

我想要做的是,对于每个'ID',能够随机选择单个'var',并且可能选择具有最多'obs'的'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))

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

使用data.table的一个选项。

我们将'data.frame'转换为'data.table'(setDT(df))。通过'ID'和'var'分组,我们创建了一个变量'N',它给出了每个组的行数(.N)。然后,我们按“ID”进行分组,并对max值为“N”(.SD[N==max(N)])的行进行子集化。 '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)][]

如果我们想在每个“ID”中选择随机“var”,我们可以使用sample选择按“ID”分组的单个“var”,获取逻辑向量(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))

答案 1 :(得分:3)

这是另一种data.table方法。开始...

library(data.table)
setDT(df)

然后,为每个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]

并且&#34;加入&#34;使用选择:

df[idvar_selected, on=c("ID","var")]