数据表聚合中的条件因子水平选择

时间:2016-02-05 19:41:24

标签: r data.table

我尝试将每个ID的data.table汇总到1行。

假设第一列代表ID,最后一列是感兴趣的因素:

mydt <- data.table(matrix(c(1,2,"Level 1", 1,12,"Level 0", 1,12,"Level 0", 2,12,"Level 3", 2,12,"Level 2"), nrow = 5, ncol = 3, byrow = TRUE))
mydt
   V1 V2      V3
1:  1  2 Level 1
2:  1 12 Level 0
3:  1 12 Level 0
4:  2 12 Level 3
5:  2 12 Level 2

我对如何聚合因子有非直观的规则:

  • 如果任何ID行存在Level 1,那么汇总的行应该为该ID <{1}}
  • 如果没有,那么如果该ID存在Level 1,则使用它
  • 如果没有,则Level 2如果存在
  • 如果没有,则Level 3

实际的Level 0非常大,并且没有实际因子级别的数字成分,它们只是字符串。此脚本每天至少运行一次,因此我尝试避免使用循环进行缓慢的预处理。

期望的结果如下所示:

data.table

但是我无法找到合适的聚合函数......

   V1 V2      V3
1:  1  8.67 Level 1
2:  2 12 Level 2

2 个答案:

答案 0 :(得分:3)

我们可以转换&#39; V3&#39;到指定顺序中指定factor的{​​{1}}。

levels

或另一个选项是mydt[, V3:= factor(V3, levels=c('Level 1', 'Level 2', 'Level 3', 'Level 0'))][, list(V2= mean(as.numeric(V2)), V3= V3[which.min(V3)]) , V1] # V1 V2 V3 #1: 1 8.666667 Level 1 #2: 2 12.000000 Level 2 通过匹配向量(按特定顺序排列)获取数字索引,得到最小值索引,得到相应的&#39; V3&#39;值,按&#39; V1&#39;分组。至于&#39; V2&#39;,它只是match的&#39; V2&#39; (在OP的帖子中显示的示例中有&#39; V2&#39;列为&#39;字符&#39;类 - 所以必须包裹mean)。

as.numeric

答案 1 :(得分:3)

我会指定V3作为您指定订单的因素,只需按V3排序即可完成其余操作:

mydt[ , V3 := factor(V3, paste("Level", c(1:3, 0)))]

mydt[order(V3), V3 := V3[1L], by = V1][]
   V1 V2      V3
1:  1  2 Level 1
2:  1 12 Level 1
3:  1 12 Level 1
4:  2 12 Level 2
5:  2 12 Level 2

如果您要聚合到较小的表格,则可以:

mydt[order(V3), .(V2 = mean(as.numeric(V2), na.rm = TRUE),
                      V3 = V3[1L]), by = V1]
   V1        V2      V3
1:  1  8.666667 Level 1
2:  2 12.000000 Level 2

请注意,由于GForce在data.table中的工作方式的特殊性,以下(最初由@Frank建议以及@ akrun&#39; s方法的精神更多)是一个错误(在当前版本中) ,至少):

mydt[, .(V2 = mean(as.numeric(V2), na.rm = TRUE),
         V3 = min(V3)), by = V1]

但这不是:

mydt[, V2 := as.numeric(V2)][, .(V2 = mean(V2, na.rm = TRUE),
                                 V3 = min(V3)), by = V1]

基本上,后一种情况使用gmindata.table内部优化的min函数,该函数适用于factor s,而前者则适用于base s至少有一个电话不是直接到GForce功能,吸引min factor,这对min(factor(1:3)) s无效( cf V2)。

自从我接受了您实际上numeric存储为min数据后,public class TestModel { @Column("column_name") private String uid; //setter and getter for uid @PrePersist protected void onCreate() { // set the uid setUid(java.util.UUID.randomUUID()); } } 方法可能更好。