2017-07-17 22 views
0

最初のデータフレームで複数回関数を適用しようとしています。簡単な例として、このデータを取る:R:同じデータフレームで複数回同じ関数を実行する

library(dplyr) 
thisdata <- data.frame(vara = seq(from = 1, to = 20, by = 1) 
         ,varb = seq(from = 1, to = 20, by = 1)) 

そして、ここでは、私はそれを介して実行したい簡単な関数である:

ので
simplefunc <- function(data) {datasetfinal2 <- data %>% mutate(varb = varb+1) 
return(datasetfinal2)} 
thisdata2 <- simplefunc(thisdata) 

thisdata3 <- simplefunc(thisdata2) 

、どのように私はこの関数を実行します、10回を言います、関数(つまりthisdata3)を呼び出す必要はありませんか?私は主にレプリケーション後の最終的なデータフレームに関心がありますが、いくつかの診断を実行できるように、生成されたすべてのデータフレームのリストを作成するとよいでしょう。助けを感謝します!

答えて

2

を免責事項を追加するのを忘れ反復回数は数よりも多い場合は特に、物事を管理するのが困難な方法です。あなたは

str(out[[10]]) 
# 'data.frame': 20 obs. of 2 variables: 
# $ vara: num 1 2 3 4 5 6 7 8 9 10 ... 
# $ varb: num 10 11 12 13 14 15 16 17 18 19 ... 

で任意の暫定値を見ることができると、ご想像のとおり

n <- 10 # number of times you need to repeat the process 
out <- vector("list", n) 
out[[1]] <- thisdata 
for (i in 2:n) out[[i]] <- simplefunc(out[[i-1]]) 

:人気の「ベストプラクティスは、」のようなもの、「data.framesのリスト」に対処するためであります最終的な結果はout[[n]]です。

これは少しReduceを使用して、そしてsimplefuncに使い捨ての第二引数を追加することを簡素化することができる。

simplefunc <- function(data, ...) { 
    datasetfinal2 <- data %>% mutate(varb = varb+1) 
    return(datasetfinal2) 
} 
out <- Reduce(simplefunc, 1:10, init = thisdata, accumulate = TRUE) 

これが効果的に行われます。

tmp <- simplefunc(thisdata, 1) 
tmp <- simplefunc(tmp, 2) 
tmp <- simplefunc(tmp, 3) 
# ... 

を(実際には、あなたが見ればソースはReduceのため、上記の最初の提案を効果的に行っています)。

simplefuncは、おそらく、ドロップすることができない他の引数を持っています

simplefunc <- function(data, ..., otherarg, anotherarg) { 
    datasetfinal2 <- data %>% mutate(varb = varb+1) 
    return(datasetfinal2) 
} 

あなたは(共通/デフォルトの方法です)、「名前で」の代わりにより、位置パラメータを渡すためにsimplefuncに他のすべての呼び出しを変更する必要がありますけれども。

編集:あなたが知っている*それははるかに良いだろう*

Reduce(function(x, ign) simplefunc(x), 1:10, init = thisdata, accumulate = TRUE) 
+0

これは新しい問題を設定する必要があるかもしれませんが、2つのデータフレームをどのようにreduce関数に送りますか? (例えば、初期点で)。 – SlyGrogger

+0

あなたが何をしようとしているのかは分かりません.2つのデータフレームに対してこれを別々に行うことを意味する場合は、それを2回実行します(別の方法は簡単ではありません)。 2つのデータフレームの組み合わせを意味するならば、それはあなたが 'rbind'か' cbind'のような組み合わせのどちらを意味するかによって決まります。 – r2evans

+0

申し訳ありませんが、説明するのは少し難しいです。私は、ここで問題をより詳細に概説してきました:https://stackoverflow.com/questions/45242969/r-using-reduce-with-custom-functionそれでは、関数からの出力を後続の反復に渡すことについての柔軟性が求められます。それにもかかわらず、上記の答えは素晴らしいです。 – SlyGrogger

0

我々はforループ

thisdata1 <- thisdata 
for(i in 2:3){ 
    assign(paste0('thisdata', i), value = simplefunc(get(paste0('thisdata', i-1)))) 
} 

注1使用することができます。操作がlist内に容易に行うことができ、地球環境に個々のオブジェクトを作成しない方がよいが。

注2:個別に複数の同一構造のdata.framesに対処する以前の

+2

:あなたは編集simplefunc、あなたは常にイテレータ/カウンタを無視するように無名関数を使用することができます(あるいはしたくない)ことができない場合'assign'を使うのではなく、データフレームのリストを持っています... – r2evans