2017-06-14 6 views
0

Ich habe eine CSV-Liste mit Kostenschätzungen, wobei jede Zeile für jede Einzelpostenschätzung eine niedrigere (l), mittlere (c) und obere (u) Bereichsschätzung enthält welches in Excel von Nicht-R-Benutzern erstellt wird. Ein Beispiel für die CSV-Daten, die ich in R gelesen haben, ist wie folgt:Monte-Carlo-Simulation (Dreiecksverteilung) über Zeilen von CSV-Kostendaten

  Item  l  c  u 
     <chr> <int> <int> <int> 
1 “CostItem1” 1500 1900 2600 
2 “CostItem2” 2400 3200 4400 
3 “CostItem3” 500 1000 1500 

Jede Zeile wird dann in einer Dreiecksverteilungsfunktion (Bibliothek (Dreieck)) wie folgt über eine Anzahl von Iterationen (läuft = 10000 verwendet in diesem Fall):

CostItem1 <- rtriangle(runs, l, u, c) 

zur Zeit eingeben I manuell die Bereichsschätzungsdaten für jede Kostenposition (CostItem1, CostItem2 usw.) in der rtriangle Funktion.

Meine Frage ist:

Wie kann ich eine Loop-Funktion oder einem anderen Ansatz schaffen dies aus der CSV-Datei direkt zu tun, wenn es in R gelesen wird? Als Neuling habe ich keine Ahnung, wie ich das angehen soll und die ganze Google-Suche hat nichts ergeben.

Die Datenkostenblock wird dann in einem neuen Datenrahmen (TotalCostEstimate) verschmolzen, die 10000-Simulationen und jeder die modellierten Gesamtkostendaten (Totalcost) summiert Zeile enthält bieten:

kann
TotalCostEstimate<-data.frame(CostItem1 ,CostItem2 ,TotalCost=rowSums(x)) 

Von hier aus werden die Daten sein grafisch dargestellt und zur Analyse und Entscheidungsfindung präsentiert. Für eine kleine Anzahl von Kostenelementen ist die manuelle Eingabe nicht zu schlecht, aber manchmal habe ich Zeilen> 50 und ich möchte das nicht 50 mal machen !!

Vielen Dank, dass Sie sich die Zeit genommen haben.

Antwort

0

Anstatt es direkt aus der CSV-Datei zu machen, lesen Sie besser die CSV-Datei in eine Matrix, erstellen Ihre Gesamtkostenmatrix und führen dann die for-Schleife aus, um die Werte zu simulieren.

Zum Beispiel auf diese Weise:

runs<-1000 #Set number of runs 
Info_costs<- read.csv("Your_file_name.csv") #Read in the information 
Total_cost_items<-matrix(,nrow=runs,ncol=length(Info_costs$Item)) #Create an empty matrix to contain your simulations 
for (i in 1:length(Info_costs$Item)) 
    {Total_cost_items[,i]<-rtriangle(n=runs,Info_costs$l[i],Info_costs$u[i],Info_costs$c[i]) } 
#Fill the matrix 
Total_cost_items<-data.frame(Total_cost_items, rowSums(Total_cost_items)) #append the matrix with the row sums 

Unter Umständen müssen Sie die richtigen Dateinamen die read.csv Funktion mit Optionen und natürlich optimieren, so dass es Ihre Datei korrekt liest. Sie können auch später die Spalten des Datenrahmens in etwas nützlicheres umbenennen

+0

Maarten, danke das klappt wirklich gut. Wie Sie sagen, muss ich die Spaltennamen anpassen. Ich denke, dass ich sie auf eine Reihe Zählung der CSV-Daten basieren werde, um zu erlauben, dass mehrere Einzelteile hinzugefügt werden und dann eine 'n' Reihenanordnung für einfache Benennung verursachen. – Nick

+0

@nick_dawe Gern geschehen. Der Spaltenname klingt nach einer guten Idee, wenn Sie den Code später in einer angehängten CSV-Datei verwenden möchten. Nicht sicher, was Sie mit einer 'n' Reihenanordnung meinen –

0

Sie können Ihre Daten unter Verwendung read.csv lesen und es als data.frame behalten. Hier einige Dummy-Daten:

df <- data.frame(Item=letters[1:3], l=1:3, c=2:4, u=3:5) 
df 

    Item l c u 
1 a 1 2 3 
2 b 2 3 4 
3 c 3 4 5 

Sie foreach verwenden können und dplyr zu erreichen, was Sie wollen:

library(foreach) 
library(dplyr) 

df <- foreach(I=1:nrow(df), .combine=rbind) %do% rtriangle(10,df$l[I],df$c[I],df$u[I]) %>% 
as.data.frame() %>% 
mutate(sum = rowSums(.)) 

Dies wird durch jede Reihe von df laufen, führen rtriangle, binden die resultierenden Daten in ein matrix , wandeln Sie die matrix in eine data.frame um, auf der Sie rowSums berechnen können.

Mein Ausgangs

V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 sum 
1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 
2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 
3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 
+0

Chi Pak, danke für Ihre Antwort. Als ich Ihren Code ausführte, erstellte er 10 Spalten basierend auf den Zeilen. Maartens Code lieferte die Antwort, die ich brauchte. Danke noch einmal. – Nick

+0

Ich denke Ihre Antwort wäre in der Spalte "sum" zu finden, aber ich bin froh, dass Sie Ihre Antwort trotzdem bekommen haben. – CPak

0

Gelöst - Dank Punt @Maarten!

dachte, ich würde die endgültige Arbeitslösung schreiben:

TotalCostEstimate<-matrix(,nrow=runs,ncol=length(basedata$Item)) #Create an empty matrix to contain your simulations 
for (i in 1:length(basedata$Item)) # Prepare distributions based on the distribution type select (1 [triangle] or 2 [discrete]) 
{if (basedata$DistType[i] == 1) { 
     TotalCostEstimate[,i]<-rtriangle(n=runs,basedata$l[i],basedata$u[i],basedata$c[i]) 
}else{ 
     TotalCostEstimate[,i]<- sample(c(0,basedata$u[i]),runs,replace=TRUE)   
     }} 
#Fill the matrix 
TotalCostEstimate<-data.frame(TotalCostEstimate, rowSums(TotalCostEstimate)) #append the matrix with the row sums 
for (i in 1:length(basedata$Item)) 
{colnames(TotalCostEstimate)[i]<-basedata$Item[i] } # Rename the column names to the cost items from base data 
#Rename the last column based on the number of cost items 
i<-length(basedata$Item) 
colnames(TotalCostEstimate)[i+1]<-"TotalCost" 

Wichtig zu beachten, dass ich die CSV modifiziert, um ein neues Feld ‚DistType‘ aufzunehmen, die der Benutzer die Art der Verteilung auswählen können, in der die Verwendung Simulation - diskret (ein oder aus) oder dreieck:

  Item  l  c  u DistType 
      <chr> <int> <int> <int> <int> 
1  “CostItem1” 1500 1900 2600  1 
2  “CostItem2” 2400 3200 4400  1 
3  “CostItem3” 500 1000 1500  1 
4 “DiscCostItem4”  0  0 1500  2 

I modifizierte auch die Loop-Funktion der Kosten Itemnamen der CSV-Datei und deren Zuordnung zu den Spalten des Ausgangs mit den letzten summierten Spalten aufzunehmen [i +1] wird 'TotalCost' genannt. Dies erlaubte den Ausgaben/Plots automatisch zu betiteln (wiederum unter Verwendung einer Schleife) basierend auf den Spaltennamen.

+0

Sorry sollte mein Handy nicht benutzen. Ich meinte: Schön, aber Sie brauchen eigentlich keine Schleife für die Spaltennamen. colnames (TotalCostEstimate) [1: Länge (basedata $ Item)] <- basedata $ Item sollte den Trick machen und die Berechnung beschleunigen –

+0

Danke nochmal Maarten, werde es versuchen. – Nick

Verwandte Themen