2017-03-02 111 views
1

我正在嘗試模擬裝配線。我有一份零件清單和他們在每個車站花費多少時間。我試圖通過流水線每次發送一個零件並記錄每個車站的時間。然而,我有這樣的工作方式是嵌套在for循環中的for循環。必須有更好的方法來做到這一點。用for循環向量化索引

parts <- data.frame(JobNum = sample(c('a','b','c','d'),400,replace=TRUE) 
,DS.CT = sample.int(10,400,replace=TRUE) 
,C1.CT = sample.int(10,400,replace=TRUE) 
,C2.CT = sample.int(10,400,replace=TRUE) 
,C3.CT = sample.int(10,400,replace=TRUE) 
,C4.CT = sample.int(10,400,replace=TRUE) 
,C5D5.CT = sample.int(10,400,replace=TRUE) 
,C6D6.CT = sample.int(10,400,replace=TRUE) 
,C5D7.CT = sample.int(10,400,replace=TRUE) 
,C6D8.CT = sample.int(10,400,replace=TRUE) 
,C7CD.CT = sample.int(10,400,replace=TRUE) 
) 

LineParts <- parts[sample(nrow(parts),234,replace=FALSE),] 

#Initialize Dip collecting variables 
DS <- c() 
D1 <- c() 
D2 <- c() 
D3 <- c() 
D4 <- c() 
D5 <- c() 
D6 <- c() 
D7 <- c() 
D8 <- c() 
D9 <- c() 

for(i in 1:dim(parts)[1]){ 

#Create temporary dataframe for use in indexing line 
LinePartsTemp <- data.frame(matrix("",nrow=234,ncol=11)) 
colnames(LinePartsTemp)=names(LineParts) 
LinePartsTemp$JobNum <- as.character(LinePartsTemp$JobNum) 
LinePartsTemp$DS.CT <- as.integer(LinePartsTemp$DS.CT) 
LinePartsTemp$C1.CT <- as.integer(LinePartsTemp$C1.CT) 
LinePartsTemp$C2.CT <- as.integer(LinePartsTemp$C2.CT) 
LinePartsTemp$C3.CT <- as.integer(LinePartsTemp$C3.CT) 
LinePartsTemp$C4.CT <- as.integer(LinePartsTemp$C4.CT) 
LinePartsTemp$C5D5.CT <- as.integer(LinePartsTemp$C5D5.CT) 
LinePartsTemp$C6D6.CT <- as.integer(LinePartsTemp$C6D6.CT) 
LinePartsTemp$C5D7.CT <- as.integer(LinePartsTemp$C5D7.CT) 
LinePartsTemp$C6D8.CT <- as.integer(LinePartsTemp$C6D8.CT) 
LinePartsTemp$C7CD.CT <- as.integer(LinePartsTemp$C7CD.CT) 

#Index line 
for(j in 1:dim(LineParts)[1]){ 
    LinePartsTemp[j+1,] <- LineParts[j,] 
} 

#put new part into system 
LinePartsTemp[1,] <- parts[i,] 

#update the list of parts on the line 
LineParts <- LinePartsTemp 

#Append CT values at stations 
DS <- append(DS,LineParts[1,'DS.CT']) 
D1 <- append(D1,LineParts[10,'C1.CT']) 
D2 <- append(D2,LineParts[26,'C2.CT']) 
D3 <- append(D3,LineParts[42,'C3.CT']) 
D4 <- append(D4,LineParts[57,'C4.CT']) 
D5 <- append(D5,LineParts[85,'C5D5.CT']) 
D6 <- append(D6,LineParts[120,'C6D6.CT']) 
D7 <- append(D7,LineParts[167,'C5D7.CT']) 
D8 <- append(D8,LineParts[210,'C6D8.CT']) 
D9 <- append(D9,LineParts[234,'C7CD.CT']) 

} 

編輯:添加樣本數據

+0

你需要有一個通過'lapply'閱讀:既部分LineParts分配重新運行相同的隨機數之前與發佈樣本數據進行測試,必須設置樣品種子,set.seed(###),以節省大量的代碼。 (LinePartsTemp [c(「var1」,「var2」)],as.integer)''''''另外,如果你用一些簡化的數據提供一個可重複的例子,你將更有可能得到答案。 – thelatemail

+0

謝謝,我添加了一些示例數據,並將考慮lapply。 –

回答

1

考慮與避免初始化空容器中,再使用大量的,獨立的環境中的對象追加到他們的列表互動。以下只有兩個對象用於輸入。

  1. 首先,建立的LineParts dataframes列表,LineParts_dfList
  2. 然後,所需要的數據點提取到載體的名單,stations_veclist

你會發現數據幀列表的lapply使用<<-運營商,因爲LineParts需要使用更新的值被重複使用,以更新全局對象(外部本地函數的範圍):

LineParts_dfList <- lapply(seq(nrow(parts)), function(i){  
    #Index line 
    LinePartsTemp <- parts[1,] 
    LinePartsTemp[2:nrow(LineParts),] <- LineParts[1:nrow(LineParts)-1,] 

    #put new part into system 
    LinePartsTemp[1,] <- parts[i,] 

    #update the list of parts on the line 
    LineParts <<- LinePartsTemp  
}) 

# Extract CT values at stations 
stations_veclist <- 
    list(
    DS = vapply(LineParts_dfList, function(df) df[1,'DS.CT'], numeric(1)), 
    D1 = vapply(LineParts_dfList, function(df) df[10,'C1.CT'], numeric(1)), 
    D2 = vapply(LineParts_dfList, function(df) df[26,'C2.CT'], numeric(1)), 
    D3 = vapply(LineParts_dfList, function(df) df[42,'C3.CT'], numeric(1)), 
    D4 = vapply(LineParts_dfList, function(df) df[57,'C4.CT'], numeric(1)), 
    D5 = vapply(LineParts_dfList, function(df) df[85,'C5D5.CT'], numeric(1)), 
    D6 = vapply(LineParts_dfList, function(df) df[120,'C6D6.CT'], numeric(1)), 
    D7 = vapply(LineParts_dfList, function(df) df[167,'C5D7.CT'], numeric(1)), 
    D8 = vapply(LineParts_dfList, function(df) df[210,'C6D8.CT'], numeric(1)), 
    D9 = vapply(LineParts_dfList, function(df) df[234,'C7CD.CT'], numeric(1)) 
) 

,並避免許多vapply調用,考慮綁定所有LineParts數據幀項到一個大數據幀中,LinePartsAll(對於234 X 400 N = 93,600 obs),然後提取值se quentially按行:

LinePartsAll <- do.call(rbind, LineParts_dfList) 

otherstations_veclist <- 
    list(
    DS = LinePartsAll[seq(1,93600, by=234),'DS.CT'], 
    D1 = LinePartsAll[seq(10,93600, by=234),'C1.CT'], 
    D2 = LinePartsAll[seq(26,93600, by=234),'C2.CT'], 
    D3 = LinePartsAll[seq(42,93600, by=234),'C3.CT'], 
    D4 = LinePartsAll[seq(57,93600, by=234),'C4.CT'], 
    D5 = LinePartsAll[seq(85,93600, by=234), 'C5D5.CT'], 
    D6 = LinePartsAll[seq(120,93600, by=234), 'C6D6.CT'], 
    D7 = LinePartsAll[seq(167,93600, by=234),'C5D7.CT'], 
    D8 = LinePartsAll[seq(210,93600, by=234), 'C6D8.CT'], 
    D9 = LinePartsAll[seq(234,93600, by=234), 'C7CD.CT'] 
) 

並檢查,此更新,更快的方法不一樣repoduce最終值原雙for循環過程。

all.equal(DS, stationsList$DS) 
# [1] TRUE 
all.equal(D1, stationsList$D1) 
# [1] TRUE 
all.equal(D9, stationsList$D9) 
# [1] TRUE 

all.equal(stations_veclist, otherstations_veclist) 
# [1] TRUE