2016-08-03 14 views
0

類似の質問は既に聞かれましたが、私の特定の問題を解決できませんでした。私は.Rファイル( "Mycalculus.R")は、データフレームのサブセットに適用する必要がある多くの基本的な計算を含んでいます: "year"のモダリティが数値でない(yearA、yearB、yearC)値。このファイルは、Rdaファイルに保存する必要がある新しいデータフレームを生成します。ここでは(この1つは明らかに動作しません)私はコードがforループでのように見えることを期待するものである:ここではサブセットをループし、ファイルをソースにして結果をデータフレームに保存します

id <- identif(unlist(df$year)) 
for (i in 1:length(id)){ 
    data <- subset(df, year == id[i]) 
    source ("Mycalculus.R", echo=TRUE) 
    save(content_df1,file="myresults.Rda") 
} 

はメインdata.frameのDFの正確である:

ここ
obs year income gender ageclass weight 
1  yearA 1000  F   1   10 
2  yearA 1200  M   2   25 
3  yearB 1400  M   2   5 
4  yearB 1350  M   1   11 

ソースファイル "Mycalculus.R"は、 "データ"と呼ばれるデータフレームの列に多数の基本計算を適用し、df1に基づいて2つの新しいデータフレームdf1とdf2を作成します。ここで抽出物である:

data <- data %>% 
    group_by(gender) %>% 
    mutate(Income_gender = weighted.mean(income, weight)) 
data <- data %>% 
    group_by(ageclass) %>% 
    mutate(Income_ageclass = weighted.mean(income, weight)) 

library(GiniWegNeg) 
gini=c(Gini_RSV(data$Income_gender, weight), Gini_RSV(data$Income_ageclass,weight)) 

df1=data.frame(gini) 
colnames(df1) <- c("Income_gender","Income_ageclass") 
rownames(df1) <- c("content_df1") 

df2=(1/5)*df1$Income_gender+df2$Income_ageclass 
colnames(df2) <- c("myresult") 
rownames(df2) <- c("content_df2") 

最後に、私はこのような2つのデータフレームを得るようにするため:

    Income_Gender Income_Ageclass  
content_df1   ....    ....  

そして、DF2用:

    myresult  
content_df2   ....   

をしかし、私はDF1保存する必要があるとcontent_df1とcontent_df2の行名がサブセットごとに与えられるRdaファイルとしてのRf2:

    Income_Gender Income_Ageclass  
content_df1_yearA  ....    ....  
content_df1_yearB  ....    ....  
content_df1_yearC  ....    ....  

    myresult 
content_df2_yearA  .... 
content_df2_yearB  ....  
content_df2_yearC  .... 

現在、私のプログラムは、任意のループを使用していないと仕事をしてますが乱雑されます。基本的にコードは2500行以上のコードです。 (私にトマトを投げないでください)。

誰かがこの特定のリクエストで私を助けることができましたか? ありがとうございます。ファイルを保存していない、あるいは、

calcFunc <- function(df) { 
    ## Do something to the df, then return it 
    df 
} 

processFunc <- function(fname) { 
    ## Read in your table 
    x <- read.table(fname) 

    ## Do the calculation 
    x <- calcFunc(x) 

    ## Make a new file name (remember to change the file extension) 
    new_fname <- sub("something", "else", fname) 

    ## Write the .RData file 
    save(x, file = new_fname) 
} 

### Your workflow 
## Generate a vector of files 
my_files <- list.files() 

## Do the work 
res <- lapply(my_files, processFunc) 

:あなたの手順を機能-IZE場合

+0

再現性の一例とするだけで、あなたの質問。 yearAとyearBの2つの単純なdata.framesを用意し、Mycalculus.Rファイルの例では単純な関数を1つ実行します。これにより、他の人があなたの質問の性質を理解しやすくなります。 – JasonAizkalns

答えて

2

lapply()によって呼び出される、必要な引数の定義済み関数を使用してすべてのスクリプトを1つのスクリプトに組み込むことを検討してください。 Lapplyは、最終的なdfに行をバインドできるデータフレームのリストを返します。

library(dplyr) 
library(GiniWegNeg) 

runIncomeCalc <- function(data, y){  
    data <- data %>% 
    group_by(gender) %>% 
    mutate(Income_gender = weighted.mean(income, weight)) 
    data <- data %>% 
    group_by(ageclass) %>% 
    mutate(Income_ageclass = weighted.mean(income, weight))  

    gini <- c(Gini_RSV(data$Income_gender, weight), Gini_RSV(data$Income_ageclass,weight)) 

    df1 <- data.frame(gini) 
    colnames(df1) <- c("Income_gender","Income_ageclass") 
    rownames(df1) <- c(paste0("content_df1_", y)) 

    return(df1) 
} 

runResultsCalc <- function(df, y){ 
    df2 <- (1/5) * df$Income_gender + df$Income_ageclass 
    colnames(df2) <- c("myresult") 
    rownames(df2) <- c(paste0("content_df2_", y) 

    return(df2) 
} 

dfIncList <- lapply(unique(df$year), function(i) {  
    yeardata <- subset(df, year == i) 
    runIncomeCalc(yeardata, i)  
}) 

dfResList <- lapply(unique(df$year), function(i) {  
    yeardata <- subset(df, year == i) 
    df <- runIncomeCalc(yeardata, i) 
    runResultsCalc(df, i)  
}) 

df1 <- do.call(rbind, dfIncList) 
df2 <- do.call(rbind, dfResList) 

今、あなたはスクリプト全体で調達する必要がある場合。 Mycalculus.Rで同じ2つの機能、runIncomeCalcrunResultsCalcを作成し、他のスクリプトでそれぞれを呼び出す:

library(dplyr) 
library(GiniWegNeg) 

if(!exists("runIncomeCalc", mode="function")) source("Mycalculus.R") 

dfIncList <- lapply(unique(df$year), function(i) {  
    yeardata <- subset(df, year == i) 
    runIncomeCalc(yeardata, i)  
}) 

dfResList <- lapply(unique(df$year), function(i) {  
    yeardata <- subset(df, year == i) 
    df <- runIncomeCalc(yeardata, i) 
    runResultsCalc(df, i)  
}) 

df1 <- do.call(rbind, dfIncList) 
df2 <- do.call(rbind, dfResList) 
+0

私の計算が1つのデータフレームのみを生成する場合(df1)、あなたのソリューションは完璧に動作します。私の計算が第2のデータフレーム(df1に基づいてdf2)を生成する場合、これはもはや機能しません。ここでコードはdf1の結果をもはや生成しません。私はこの点について私がより明確になるように私の質問を編集した。 – Elixterra

+0

同じfctとargsプロセスでupdateを参照してください。 df1を入力として受け取る別の関数を追加して、最後に 'rbind'に' lapply'を反復します。そして、他のスクリプトから2つの関数をソースします。 – Parfait

+0

あなたのアップデートでは、df1ではなくrunResultsCalcの部分にdfを書きました。 df2の計算はdf1の結果に基づいているので、 'df2 < - (1/5)* df1 $ Income_gender + df1 $ Income_ageclass'でなければなりません。それは目的にあったものであり、そうでない場合は、これが残りのコードに与える影響は何ですか? – Elixterra

1

すると、以下のようなワークフローを作成することができます。 processFuncsaveコールを省略し、data.frameオブジェクトのリストを返します。次に、data.table::rbindlist(res)またはdo.call(rbind, list)のいずれかを使用して、1つの大きなdata.frameオブジェクトを作成します。

+0

私の現在の.Rの計算ファイル(私は最初のステップとしてfuntional-izeする必要があります)は、計算のメインdata.frameを参照して、私はサブ設定がオーバーライドされることを恐れています。この問題は、 'by'コマンドを使用しようとしていました。私は基本的にプログラムがグループによって「何か」をするように求めていたが、「何か」はメインのデータフレームを指していた。したがって、サブグループの数だけ実行するようにプログラムを導く 'by group'命令と矛盾していましたが、メインのデータフレームではそうでした。私はここで同じ問題を抱えているのを恐れている。どう思いますか? – Elixterra

関連する問題