4

こんにちは。うまくいけば、これをやや簡単に説明できます。これはループで実行できることはわかっていますが、それには永遠に時間がかかり、この分析を Web ページの一部として実行する必要があるため、何らかの適用機能がうまく機能することを願っています。

私は2つのデータフレームを持っています。データ フレーム A には、個別の「アンカー」とそれぞれのカテゴリ値のリストがあります (これらは、既に実行された ddply からの加重平均値です)。

anchor     ecomax    ecomin     volume     price    runtime
1   9482 0.12981362 0.5714286 0.12981362 0.1324330 1.00000000
2   9488 0.01458662 0.5544864 0.01458662 0.2967270 0.04166667
3   9549 0.09734398 0.5721429 0.09734398 0.1219376 1.00000000
4   9574 0.00902656 0.5505136 0.00902656 0.1455307 0.14652568
5   9575 0.00902656 0.5505136 0.00902656 0.1460919 0.14652568
6   9576 0.07608863 0.5613563 0.07608863 0.1114813 1.00000000

データ フレーム B は同じカテゴリ値のより大きなデータ フレームですが (ここでは名前は無視してください)、アンカーごとに複数のエントリがあります。

  anchor ecomax_max_med ecomin_min_med volume_med price_med run_time_minimum_med
1   9482     0.12981362      0.5714286 0.12981362 0.1120882           1.00000000
2   9482     0.12981362      0.5714286 0.12981362 0.1686777           1.00000000
3   9488     0.01552049      0.5550000 0.01552049 0.2925363           0.04166667
4   9488     0.01292292      0.5535714 0.01292292 0.3041928           0.04166667
5   9549     0.09734398      0.5721429 0.09734398 0.1238916           1.00000000
6   9549     0.09734398      0.5721429 0.09734398 0.1184564           1.00000000

一致するアンカーに基づいて、平均 (データ フレーム A) から B のカテゴリ値を減算します。つまり、B の最初の 2 行 (アンカー 9482) は A の最初の行 (アンカー 9482 平均) との差を取り、B の次の 2 行 (アンカー 9488) は A の次の行 (アンカー 9488 平均) との差を取ります。 、 等々。

最終結果は、新しいデータ フレーム C の各行/列 (アンカー以外) が、データ フレーム B の値とそれに対応するアンカー手段 (データ フレーム A) の差になることです。これがかなり簡単であることを願っています。長いループで簡単に実行できます。これには「マッチ」または「バイ」の組み合わせが必要だと推測していますが、確信が持てず、これは非常にイライラしています。助けてください!

4

2 に答える 2

2

これがdata.table解決策です。

これは、マージABby anchor(キーとして設定されます) によって機能します。次に、e作成した式を次のように評価します。

list(ecomax_diff = ecomax_max_med - ecomax, ecomin_diff = ecomin_min_med - ecomin, volume_diff = volume_med - volume, price_diff = price_med - price, runtime_diff = run_time_minimum_med - runtime)

mapplysprintfおよびを使用しparseます。

解決策は、各 data.table に対応する列名を mapply に渡すことに依存します。

library(data.table)
DA <- data.table(A)
DB <- data.table(B)
setkey(DA, 'anchor')
setkey(DB, 'anchor')

.calls <- mapply(sprintf, as.list(names(DA)[-1]), 
  as.list(names(DB)[-1]), as.list(names(DA)[-1]), 
  MoreArgs = list(fmt = '%s_diff = %s - %s'))

.e <- parse(text = sprintf('list(%s)', paste(.calls, collapse =', ')))


DA[DB, eval(.e)]
##  anchor ecomax_diff ecomin_diff volume_diff price_diff runtime_diff
## 1:   9482  0.00000000   0.0000000  0.00000000 -0.0203448            0
## 2:   9482  0.00000000   0.0000000  0.00000000  0.0362447            0
## 3:   9488  0.00093387   0.0005136  0.00093387 -0.0041907            0
## 4:   9488 -0.00166370  -0.0009150 -0.00166370  0.0074658            0
## 5:   9549  0.00000000   0.0000000  0.00000000  0.0019540            0
## 6:   9549  0.00000000   0.0000000  0.00000000 -0.0034812            0
  • これはjoin inherited scopeを使用するため効率的です。data.table FAQ 1.11 -1.13を参照してください。

2番目の、効率は劣りますが、おそらく従うのが簡単な解決策

 # calculate the difference between the respective columns (merged appropriately
 DIFF <- DB[, names(DB)[-1],with = F] - DA[DB][, names(DA)[-1], with = F]
 # combine with the anchor column from DB 
 DC <-  cbind(DB[,list(anchor)],DIFF)
 # rename with the names from A (otherwise they will have the same as DB
 setnames(DC, names(DA))
 # It creates the correct output !
 DC
 ##    anchor      ecomax      ecomin      volume      price      runtime
 ## 1:   9482  0.00000000   0.0000000  0.00000000 -0.0203448            0
 ## 2:   9482  0.00000000   0.0000000  0.00000000  0.0362447            0
 ## 3:   9488  0.00093387   0.0005136  0.00093387 -0.0041907            0
 ## 4:   9488 -0.00166370  -0.0009150 -0.00166370  0.0074658            0
 ## 5:   9549  0.00000000   0.0000000  0.00000000  0.0019540            0
 ## 6:   9549  0.00000000   0.0000000  0.00000000 -0.0034812            0
  • -.data.table注:将来のバージョンで文字列を無視すると、これはさらに簡単になる可能性があります
于 2012-09-13T04:46:47.183 に答える
1
datmer <- merge(datA, datB)
str(datmer)
#------------------    
'data.frame':   6 obs. of  11 variables:
 $ anchor              : int  9482 9482 9488 9488 9549 9549
 $ ecomax              : num  0.1298 0.1298 0.0146 0.0146 0.0973 ...
 $ ecomin              : num  0.571 0.571 0.554 0.554 0.572 ...
 $ volume              : num  0.1298 0.1298 0.0146 0.0146 0.0973 ...
 $ price               : num  0.132 0.132 0.297 0.297 0.122 ...
 $ runtime             : num  1 1 0.0417 0.0417 1 ...
 $ ecomax_max_med      : num  0.1298 0.1298 0.0155 0.0129 0.0973 ...
 $ ecomin_min_med      : num  0.571 0.571 0.555 0.554 0.572 ...
 $ volume_med          : num  0.1298 0.1298 0.0155 0.0129 0.0973 ...
 $ price_med           : num  0.112 0.169 0.293 0.304 0.124 ...
 $ run_time_minimum_med: num  1 1 0.0417 0.0417 1 ...

 datmer2 <- cbind(datmer[,1, drop=FALSE], 
                  as.matrix(datmer[, 2:6])  - as.matrix(datmer[7:11]) )
 datmer2
#--------
  anchor      ecomax     ecomin      volume      price runtime
1   9482  0.00000000  0.0000000  0.00000000  0.0203448       0
2   9482  0.00000000  0.0000000  0.00000000 -0.0362447       0
3   9488 -0.00093387 -0.0005136 -0.00093387  0.0041907       0
4   9488  0.00166370  0.0009150  0.00166370 -0.0074658       0
5   9549  0.00000000  0.0000000  0.00000000 -0.0019540       0
6   9549  0.00000000  0.0000000  0.00000000  0.0034812       0

@mnel が行った順序で違いを使用したい場合 (BA)、列名も 2 番目のデータフレームのものと同じになるようにします。

 str( cbind(datmer[,1, drop=FALSE], as.matrix(datmer[7:11])  - as.matrix(datmer[2:6]) ) )
'data.frame':   6 obs. of  6 variables:
 $ anchor              : int  9482 9482 9488 9488 9549 9549
 $ ecomax_max_med      : num  0 0 0.000934 -0.001664 0 ...
 $ ecomin_min_med      : num  0 0 0.000514 -0.000915 0 ...
 $ volume_med          : num  0 0 0.000934 -0.001664 0 ...
 $ price_med           : num  -0.02034 0.03624 -0.00419 0.00747 0.00195 ...
 $ run_time_minimum_med: num  0 0 0 0 0 0
于 2012-09-13T04:46:14.737 に答える