2016-08-11 10 views
1

は、私ならば、私はこの計算サポートdata.table

customer TranAmount 
1: 146506 1290.49 
2: 146506 2699.00 
3: 146506 2720.00 
4: 146506 2700.00 
5: 146506  6.35 
6: 146506 2700.00 
7: 146506 2705.00 
8: 146506 2691.00 
9: 146506  500.00 
10: 146506  500.95 
11: 146506  52.00 

のように見えたdata.table今、私は私が意味するsupportにより、各量のsupportを計算したいしているとしましょうトランザクション を選択し、そのトランザクションのしきい値内にあるトランザクションがある場合、そのトランザクションのsupportは、その制限内のトランザクションの数に等しい。我々は次に、6つのトランザクションは、その範囲内にある(2700.00上または2700.00未満)、1%の閾値を考慮すればTranAmount 2700.00についての上記データ、例えば

は、そうTranAmount 2700.00ため6

あるsupport私はこの機能を書いていますが、それは遅くて確かにdata.tableではありませんが、それは仕事をして、私はこれを達成するためのよりよい方法があると確信していますが、私は考えることができません。

get_support <- function(dt,val_tolerance=0.01) { 
    support_dt <- dt[,.(customer,TranAmount)][order(TranAmount)] 
    support_dt[,support:= 0] 

    for(i in 1:nrow(support_dt)) { 
     start <- support_dt[i,TranAmount] 
     current_support <- support_dt[i,support] 
     amount_limit <- c((start - start*val_tolerance),(start + start*val_tolerance)) 
     for (j in 1:nrow(support_dt)){ 
     amount <- support_dt[j,TranAmount] 
     if(between(amount,amount_limit[1],amount_limit[2]) ==TRUE){ 
      current_support <- current_support+1 
     }else{ 
      current_support <- current_support 
     } 
     } 
     #print(current_support) 
     support_dt[i,support:=current_support] 
    } 
    print(support_dt) 
} 

これを実現するには、より良い方法をお勧めします。

答えて

4

、非エクイ結合を使用:

vals = c(2700, 500) 

DT[.(dn = vals*0.99, up = vals*1.01), on=.(TranAmount >= dn, TranAmount <= up), 
    .N 
, by=.EACHI] 

# TranAmount TranAmount N 
# 1:  2673  2727 6 
# 2:  495  505 2 

列名結果には非常に直感的ではありませんが、それらは変更される場合があります。

現在(2016年8月)、このためにはinstall the devel versionが必要です。

2

私は警告を得たが、明らかにロジックが健全だった:

ここ
dt[ , support := ave(TranAmount, TranAmount, 
          FUN= function(x) sum(abs(x -dt$TranAmount) < 0.01*x)) ] 
#--------------------------------- 
Warning messages: 
1: In x - dt$TranAmount : 
    longer object length is not a multiple of shorter object length 
2: In abs(x - dt$TranAmount) < 0.01 * x : 
    longer object length is not a multiple of shorter object length 
> dt 
    customer TranAmount support 
1: 146506 1290.49  1 
2: 146506 2699.00  6 
3: 146506 2720.00  5 
4: 146506 2700.00  6 
5: 146506  6.35  1 
6: 146506 2700.00  6 
7: 146506 2705.00  6 
8: 146506 2691.00  5 
9: 146506  500.00  2 
10: 146506  500.95  2 
11: 146506  52.00  1 
2

作品ハックdata.tableソリューションです

tvals <- df$TranAmount 
pct <- 0.01 

dfDT[, id := .I][,support := sum(TranAmount*(1-pct) <= tvals & tvals <= TranAmount*(1+pct)), by = list(id)][,id:=NULL] 

EDIT(ただしおそらくきれいな方法があります):代替data.table接近

dfDT[, support := sum(TranAmount*(1-pct) <= tvals & tvals <= TranAmount*(1+pct)), by = rownames(dfDT)] 
ここ3210

とはdplyr溶液

df %>% 
    group_by(rn=row_number()) %>% 
    mutate(support = sum(TranAmount*(1-pct) <= tvals & tvals <= TranAmount*(1+pct))) %>% 
    ungroup %>% 
    select(-rn) 

## customer TranAmount support 
##  <int>  <dbl> <int> 
## 1 146506 1290.49  1 
## 2 146506 2699.00  6 
## 3 146506 2720.00  5 
## 4 146506 2700.00  6 
## 5 146506  6.35  1 
## 6 146506 2700.00  6 
## 7 146506 2705.00  6 
## 8 146506 2691.00  5 
## 9 146506  500.00  2 
## 10 146506  500.95  2 
## 11 146506  52.00  1 

注、dfdata.frame)であり、dfDTdata.table)は、同じデータを含みます。バージョン1.9.7以降で

+0

厥本当にハック:D – Bg1850

0

はここで比較的簡単な方法data.table

x[, support := x[abs(TranAmount- .SD[,TranAmount]) < 0.01*.SD[,TranAmount] , .N], 
    by=1:NROW(x)] 

# customer TranAmount support 
# 1: 146506 1290.49  1 
# 2: 146506 2699.00  6 
# 3: 146506 2720.00  5 
# 4: 146506 2700.00  6 
# 5: 146506 6.35  1 
# 6: 146506 2700.00  6 
# 7: 146506 2705.00  6 
# 8: 146506 2691.00  5 
# 9: 146506 500.00  2 
#10: 146506 500.95  2 
#11: 146506 52.00  1 

だデータ:

x = data.table(customer=rep(146506,11), 
       TranAmount=c(1290.49, 2699.00, 2720.00, 2700.00, 6.35, 2700.00, 
          2705.00, 2691.00, 500.00, 500.95, 52.00)) 
関連する問題