代码之家  ›  专栏  ›  技术社区  ›  Chris. Z

因子内因子水平的选择

  •  2
  • Chris. Z  · 技术社区  · 9 年前

    这是我的例子:

    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”,能够随机选择一个“var”,并且可能通过选择具有最多“obs”的“var”。例如,它可以随机给出:

       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
    

    提前感谢您的帮助。

    2 回复  |  直到 9 年前
        1
  •  3
  •   Frank    9 年前

    这是另一个数据。表方法。开始。。。

    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]
    

    并使用所选内容“连接”:

    df[idvar_selected, on=c("ID","var")]
    
        2
  •  3
  •   akrun    9 年前

    一个选项使用 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))