分组时为data.table的j参数预编程组件

时间:2018-08-03 09:43:44

标签: r data.table environment

我有一个大的data.table,我经常用它编程并重复执行以下操作:

d.regionOffice <- d.input[, .(sales = sum(sales)), .(region, office)]

d.region <- d.regionOffice[, .(sales = sum(sales)), .(region)]

除了sales = sum(sales)以外,我还有其他变量会定期重用,而且通常使用更长的变量名。

有没有一种方法可以捕获此通用构造,然后在data.table中使用它?

我尝试过天真的事情,例如:

l.sales <- list(sales = sum(sales))

但是R会给您一个错误,提示“错误:未找到对象'sales'”。有解决方法吗?

请注意,我有多个常用的摘要统计信息,例如profit = sum(profit)customers = sum(customers)等,因此仅需要一个by参数的自定义函数是不够的。

2 个答案:

答案 0 :(得分:2)

如果我理解正确,那么OP正在寻找一种捷径来创建类型更少的聚合。

代替键入

if( current_user_can('administrator')) {
function display_customers_list() {
// query array
$args = array(
    'role' => 'outlet'
);
$customers = get_users($args);
if( empty($customers) )
return;

echo'<br>';
echo'<h3>Display Customer List</h3>';
echo '<form action="" method="POST">';
echo'<select class="selectpicker" data-show-subtext="true" data-live-search="true" name="select_name[]" title="Select Customer">';
foreach( $customers as $customer ){
    echo '<option value="'.$customer->data->ID.'">'.$customer->data->display_name.'</option>';
}
echo '</select>';
echo '<input type="submit" value="Select Customer">';
echo '</form>'; 


echo'<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">';
echo'<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.10.0/css/bootstrap-select.min.css" />';
echo'<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>';
echo'<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>';
echo'<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.10.0/js/bootstrap-select.min.js"></script>';

}   
add_filter( 'woocommerce_before_checkout_form', 'display_customers_list' );
}
library(data.table)
DT <- as.data.table(iris)

DT[, .(Sepal.Length = mean(Sepal.Length), Petal.Length = mean(Petal.Length)), by = Species]

我们可以写

      Species Sepal.Length Petal.Length
1:     setosa        5.006        1.462
2: versicolor        5.936        4.260
3:  virginica        6.588        5.552
cols <- c("Sepal.Length", "Petal.Length")
DT[, lapply(.SD, mean), .SDcols = cols, by = Species]

为方便起见,可以将其放在函数中:

      Species Sepal.Length Petal.Length
1:     setosa        5.006        1.462
2: versicolor        5.936        4.260
3:  virginica        6.588        5.552
agg <- function(dt, cols, grp, fct = sum) {
  dt[, lapply(.SD, fct), .SDcols = cols, by = grp]
}

agg(DT, cols, "Species", mean)
      Species Sepal.Length Petal.Length
1:     setosa        5.006        1.462
2: versicolor        5.936        4.260
3:  virginica        6.588        5.552
# using default aggregation function
agg(DT, cols, "Species")
      Species Sepal.Length Petal.Length
1:     setosa        250.3         73.1
2: versicolor        296.8        213.0
3:  virginica        329.4        277.6
# totals without grouping
agg(DT, cols, , mean)

或者,使用另一个data.table

   Sepal.Length Petal.Length
1:     5.843333        3.758
DT2 <- as.data.table(mtcars, keep.rownames = TRUE)
agg(DT2, c("wt", "hp"), "cyl", sum)
   cyl     wt   hp
1:   6 21.820  856
2:   4 25.143  909
3:   8 55.989 2929
agg(DT2, c("wt", "hp"), "cyl", length)

答案 1 :(得分:2)

另一种解决方案是仅在R中使用代码片段。最初的问题是减少重复键入的数量,这可以使用上述解决方案以编程方式完成,也可以使用RStudio在代码片段中以半手动方式完成。 / p>

在RStudio中,进入:工具>全局选项>代码>编辑代码段(在底部)

然后添加一个代码段,例如

snippet gwp
    gross.written.premium = sum(gross.written.premium)

然后,当您输入代码时,只需键入gwp [tab],它将展开为完整的代码。