1

sapplyの動作をfor ループに置き換えたい。(興味がある場合は、その理由についてさらに下を参照してください。)

これが私のコードのsapplyバージョンの簡略化です:

slow_function=function(n) c(n*n, 0, (-n)^n, -1, +1)
quick_analysis=function(res) res[1]+res[3]

results=sapply(1:8,function(n){
  res=slow_function(n)
  a=quick_analysis(res)
  b=table(sign(res))
  list(
    a=a,
    up=b['1'],
    down=b['-1'],
    level=b['0']
    )
  })

それは私に与えます:

      [,1] [,2] [,3] [,4] [,5]  [,6]  [,7]    [,8]    
a     0    8    -18  272  -3100 46692 -823494 16777280
up    2    3    2    3    2     3     2       3       
down  2    1    2    1    2     1     2       1       
level 1    1    1    1    1     1     1       1  

(これは良いことですが、実際には n の値を行として、a、up、down、level を列として転置したいのですが、問題ありません。その方法は知っています。)

それを for ループにすると:

results=vector()
for(n in 1:8){
  res=slow_function(n)
  a=quick_analysis(res)
  b=table(sign(res))
  results[n]=list(
    a=a,
    up=b['1'],
    down=b['-1'],
    level=b['0']
    )
  }

次に、次のような8つの警告メッセージが表示されます。

1: In results[n] = list(a = a, up = b["1"], down = b["-1"], level = b["0"]) :
  number of items to replace is not a multiple of replacement length

結果は大きく異なります。

[[1]]
[1] 0

[[2]]
[1] 8

[[3]]
[1] -18

[[4]]
[1] 272

[[5]]
[1] -3100

[[6]]
[1] 46692

[[7]]
[1] -823494

[[8]]
[1] 16777280

何が起こっているのか、なんとなくわかります。私が知らないのは、私が望む結果を得るための魔法の呪文です! matrix()結果をorに初期化list()して、同じ出力で試してみました。

ASIDE : なぜ for ループを使いたいのですか? 実際には、sapply ループのパスごとに 2 つの計算を実行したいと考えています。つまり、8 回の呼び出しだけでslow_function16 行の結果が返されます。sapply が許可した場合、私のコードは次のようになります。

results=sapply(1:8,function(n){
  res=slow_function(n)
  a=quick_analysis(res)
  b=table(sign(res))
  list(
    a=a,
    up=b['1'],
    down=b['-1'],
    level=b['0']
    )
  res=-res  #Modify res
  a=quick_analysis(res)
  b=table(sign(res))
  list(
    a=a,
    up=b['1'],
    down=b['-1'],
    level=b['0']
    )
  })

望ましい出力: (フォーマットがオフになっていて申し訳ありません。手動で作成する必要がありました)

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]  [,13]   [,14] [,15]   [,16]   
a     0     0    8     -8   -18  18    272  -272 -3100 3100  46692  -46692 -823494 823494 16777280 -16777280
up    2     2    3     1    2    2     3     1    2     2     3      1      2       2      3        1
down  2     2    1     3    2    2     1     3    2     2     1      3      2       2      1        3
level 1     1    1     1    1    1     1     1    1     1     1      1      1       1      1        1  
4

2 に答える 2

2

これは、データなしでこれを達成する方法と、あなたが何を求めているかを知るための暗闇の中でのショットです。

slow_function=function(n) c(n*n, 0, (-n)^n, -1, +1)
quick_analysis=function(res) res[1]+res[3]

results=lapply(1:8,function(i){
  res=slow_function(i)
  FUN <- function(res.in) {
      a=quick_analysis(res.in)
      b=table(sign(res.in))
      data.frame(
       a=a,
       up=b['1'],
       down=b['-1'],
       level=b['0']
       )
  }
  data.frame(id=c("p", "n"), it=i, rbind(FUN(res), FUN(-res)))
})

DAT <- do.call(rbind, results)
with(DAT, DAT[order(id, it), ]) #maybe the order you're after

編集:

これにより、必要なものが得られます(必要な出力がわからなかったため、インデックス作成とIDは必要ありませんでした。適切と思われるテーマを削除できます)。

rownames(DAT) <- NULL
t(DAT[, -c(1:2)])
于 2012-07-23T03:21:36.717 に答える
1

sapplyは、すべて同じ長さの場合、デフォルトで結果を単純化します。したがって、forループが返すさまざまなサブリストを手動で組み合わせる必要があります。

results2 = list()
for (n in 1:8){
  res=slow_function(n)
  a=quick_analysis(res)
  b=table(sign(res))
  results2[[n]] = list(
    a=a,
    up=b['1'],
    down=b['-1'],
    level=b['0']
  )

}

do.call(cbind, results2)
于 2012-07-23T09:27:16.497 に答える