1

私がやりたいことは、ループの代わりに apply を使用して、文字列の 2 つの配列を行ごとに比較することです。たとえば、x.str の行 1 と y.str の行 1 を比較します。

x.str

     [,1] [,2] [,3] [,4]
[1,] "c"  "o"  "m"  "e" 
[2,] "g"  "o"  "n"  "e" 
[3,] "b"  "o"  "o"  "d" 
[4,] "f"  "i"  "n"  "e" 

y.str

     [,1] [,2] [,3] [,4]
[1,] "t"  "o"  "o"  "t" 
[2,] "j"  "a"  "m"  "m" 
[3,] "b"  "e"  "e"  "n" 
[4,] "l"  "e"  "t"  "s" 

ループとして書く場合:

A = array(0,dim=dim(x.str1))
for(i in 1:length(x.str[,1])){
    A[i,] = ifelse(x.str[i,] %in% y.str[i,],1,0)
}

出力すると:

     [,1] [,2] [,3] [,4]
[1,]    0    1    1    0
[2,]    0    0    1    0
[3,]    1    0    0    0
[4,]    0    1    0    0

ただし、実数配列の次元は約になります。

array(0,dim=c(10000,12)

したがって、代わりにループよりもはるかに高速な apply を使用したいと考えました。私はこのサイトやその他のサイトをすべて見て、さまざまな方法を試しましたが、適用内で処理されている現在の行を選択して関数で使用する方法がわかりません。同様の投稿では、次の使用が提案されています。

nrow()
rownames()

私はそれらを次のように使用しました:

stringCom = function(x){
     i = nrow(x)
     ifelse(x.str[i,] %in% y.str1[i,],0,1)
}
apply(x.str,1,stringCom)

しかし、私が取得し続けるのはエラーだけです。私が試してみました:

test = function(x){

  r = nrow(x)
  r
}
apply(x.str,1,test)

出力として NULL を与えるだけです。行名、NROW、名前などでも同様のことが起こります。おそらく非常に単純な答えがあると思いますが、それを見つけることができないようです。

任意の提案/ヘルプをいただければ幸いです。

4

1 に答える 1

0

一度に 2 つのことを繰り返したい場合は、何らかの形式のmapply. 入力データの例を次に示します。

x.str<-matrix(strsplit("cgbfoooimnoneede","")[[1]], ncol=4)
y.str<-matrix(strsplit("tjbloaeeomettmns","")[[1]], ncol=4)

次に、次のようなことができます

t(mapply(function(a,b) a%in%b, 
    split(x.str, row(x.str)), split(y.str, row(y.str)))+0)

#   [,1] [,2] [,3] [,4]
# 1    0    1    0    0
# 2    0    0    0    0
# 3    1    0    0    0
# 4    0    0    0    1

あなたが書いたコードと同じものを返します

A = array(0,dim=dim(x.str))
for(i in 1:length(x.str[,1])){
    A[i,] = ifelse(x.str[i,] %in% y.str[i,],1,0)
}
A
#      [,1] [,2] [,3] [,4]
# [1,]    0    1    0    0
# [2,]    0    0    0    0
# [3,]    1    0    0    0
# [4,]    0    0    0    1

しかし、for ループが遅いとは限りません。さまざまな戦略をベンチマークして、特定のアプリケーションに最適なものを確認する必要があります。最大のボトルネックは通常のメモリ管理です。結果に必要なメモリを事前に定義している限り、多くの場合、for ループは高速になります。

于 2015-02-03T00:31:38.283 に答える