5

たとえば、私は行列を持っていますk

> k
  d e
a 1 3
b 2 4

k に関数を適用したい

> apply(k,MARGIN=1,function(p) {p+1})
a b
d 2 3
e 4 5

ただし、その時点で関数がどの行に適用されているかを知ることができるようrownameに、行の も出力したいと思います。apply

次のようになります。

apply(k,MARGIN=1,function(p) {print(rowname(p)); p+1})

しかし、私は本当にRでそれを行う方法を知りません.誰かに何か考えがありますか?

4

4 に答える 4

12

これは、あなたが求めていると思うものに対するきちんとした解決策です。(わかりやすくするために、入力行列と呼んでいます。この例では、2 列と 10 行があり、行にはmatabc1から abc10 までの名前が付けられています。)kmat

以下のコードでは、結果out1は計算したいもの (apply コマンドの結果) です。結果out2は、作業中の行名を出力することを除いて、 と同じようout1に出力されます (行ごとに 0.3 秒の遅延を入れたので、実際にこれを行うことがわかります。コードを完全に実行したい場合は、これを削除してください)明らかにスピード!)

私が思いついたトリックは、行番号 (1 から n) を の左側に cbind し (1matつの列を追加した行列を作成するため)、次にこれを使用して の行名を参照することでしmatた。x = y[-1]関数内の実際の計算 (ここでは 1 の追加) が行番号の最初の列を無視することを意味する行に注意してください。これは、 に対して行われる計算と同じであることを意味しout1ます。行に対して実行したいどんな種類の計算も、この方法で実行できます。y存在しなかったふりをして、 を使用して目的の計算を定式化するだけxです。お役に立てれば。

set.seed(1234)
mat = as.matrix(data.frame(x = rpois(10,4), y = rpois(10,4)))
rownames(mat) = paste("abc", 1:nrow(mat), sep="")
out1 = apply(mat,1,function(x) {x+1})
out2 = apply(cbind(seq_len(nrow(mat)),mat),1,
             function(y) {
                           x = y[-1]
                           cat("Doing row:",rownames(mat)[y[1]],"\n")
                           Sys.sleep(0.3)
                           x+1
                          }
            )

identical(out1,out2)
于 2012-06-09T06:50:45.830 に答える
4

apply 呼び出しの外で変数を使用して、行インデックスを追跡し、行名を追加の引数として関数に渡すことができます。

idx <- 1
apply(k, 1, function(p, rn) {print(rn[idx]); idx <<- idx + 1; p + 1}, rownames(k))
于 2012-06-09T00:15:01.107 に答える
0

これはうまくいくはずです。関数は、cat()関数の評価中に結果を出力するときに使用するものです。paste()逆に、文字ベクトルを返すだけで、コマンド ウィンドウには送信しません。

以下のソリューションでは、クロージャーとして作成されたカウンターを使用して、関数が以前に実行された回数を「記憶」できるようにします。グローバル assign の使用に注意してください<<-。ここで何が起こっているのかを本当に理解したい場合は、この wiki https://github.com/hadley/devtools/wiki/を読むことをお勧めします。

これを行う簡単な方法があるかもしれないことに注意してください。私の解決策は、適用関数内で一般的な手段を使用して現在の行の行番号または行名にアクセスする方法がないことを前提としています。前述のように、これはループでは問題ありません。

k <- matrix(c(1,2,3,4),ncol=2)
rownames(k) <- c("a","b")
colnames(k) <- c("d","e")


make.counter <- function(x){
    i <- 0
    function(){
        i <<- i+1
        i   
    }
}

counter1 <- make.counter()

apply(k,MARGIN=1,function(p){
    current.row <- rownames(k)[counter1()]
    cat(current.row,"\n")
    return(p+1)
})
于 2012-06-08T23:02:41.950 に答える
-3

私の知る限り、 でそれを行うことはできませんが、データ フレームapplyの をループすることはできます。rownames下手な例:

lapply(rownames(mtcars), function(x) sprintf('The mpg of %s is %s.', x, mtcars[x, 1]))
于 2012-06-08T22:55:59.287 に答える