2017-12-12 18 views
0

ここでは、解決しようとしている問題の例を示します。R - 関数内のデータフレームの参照列にベクトル引数を渡す

は私はA、B及びCからの2つの値を見つけるためにDとA、B、およびCの値の各々の間の距離を計算する、各行のデータフレーム

x<-matrix(1:9, nrow= 3, ncol= 3) 
y<-c(1,100,2) 
z<-c("A","B","C","D") 
df<-cbind(x,y) 
colnames(df)<-z 

    A B C D 
[1,] 1 4 7 1 
[2,] 2 5 8 100 
[3,] 3 6 9 2 

を有しますDに最も近い。

これは私の最新の試みでした。

test<-function(x,y,z){ 
    d<-abs(x-y) 
    df<-data.frame(z,d) 
    df<-df[order(d),] 
    d<-c(df[1:2,1]) 
    d<-paste(d[1],"-",d[2],sep="") 
} 



results<adply(test, 1, transform, res = test(
    c("A","B","C"),D,1:3])) 

これは私がこのようなデータフレームであることを結果を望んでいます

Error in splitter_a(.data, .margins, .expand, .id) : Invalid margin 

を取得していますエラーさ:

 A B C D res 
[1,] 1 4 7 25 A-B 
[2,] 2 5 8 26 C-B 
[3,] 3 6 9 27 A-B 

提供すべてのヘルプは大歓迎です。

NT

編集 - 提案答えは私のテストケースで働いていたが、私には、実際のシナリオを翻訳したときに動作しません。

Error in x[c(columns[5:9])] - x[target] : 
    non-numeric argument to binary operator 

私はデータの値を確認している:ここではこれは私が次のエラーを取得していたスクリプトが私にシナリオ

apply(DF, 1, function(x){ 
    paste(c("0%","25%","50%","75%","100%")[order(abs(x[c(columns[1:5])] - x["target"]))][1:2], collapse = "-") 
}) 

を変換する方法DF

のサンプル
0%  25%  50%  75% 100% target 
1 350.00 350.0000 380.610 380.6100 416.25 425.0 
2 350.00 350.0000 350.000 350.0000 350.00 425.0 
3 223.83 383.6800 414.890 472.3050 529.20 425.0 
4 442.36 442.9625 443.565 444.1675 444.77 472.8 
5 466.00 525.4800 529.200 529.2000 529.20 465.6 
6 350.00 357.1650 364.330 371.4950 378.66 513.6 

をです数字である

答えて

2
apply(df, 1, function(x){ 
    paste(c("A", "B", "C")[order(abs(x[c("A", "B", "C")] - x["D"]))][1:2], collapse = "-") 
}) 
#[1] "A-B" "C-B" "A-B" 

UPDATE

#DATA 
df = read.table(strip.white = TRUE, 
       stringsAsFactors = FALSE, 
       header = TRUE, 
       check.names = FALSE, 
       text = "0%  25%  50%  75% 100% target 
       1 350.00 350.0000 380.610 380.6100 416.25 425.0 
       2 350.00 350.0000 350.000 350.0000 350.00 425.0 
       3 223.83 383.6800 414.890 472.3050 529.20 425.0 
       4 442.36 442.9625 443.565 444.1675 444.77 472.8 
       5 466.00 525.4800 529.200 529.2000 529.20 465.6 
       6 350.00 357.1650 364.330 371.4950 378.66 513.6") 

apply(df, 1, function(x){ 
    paste(names(x)[order(abs(x[1:5] - x[6]))][1:2], collapse = "-") 
}) 
#   1   2   3   4   5   6 
#"100%-50%" "0%-25%" "50%-25%" "100%-75%" "0%-25%" "100%-75%" 
+0

答えは私の実lief 1私のテストシナリオのために働いたが、いないように私は、いくつかの追加情報を追加しました。 – Terno

+1

完璧!それは素晴らしい作品です。私はそれをループとして実行していましたが、私はplyr、apply、および同様のパッケージを使って物を最適化することにもっと頼っています。 もう一度おねがいします – Terno

関連する問題