1

I am trying to simulate an assembly line. I have a list of parts and how much time they spend at each station. I am trying to send the parts through the assembly line one at a time and record the times at each station. However, the way I have this working is with a for loop nested inside a for loop. There has to be a better way to do this.

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'])

}

EDIT: added sample data

2
  • You need to have a read through ?lapply to save you reams of code. Instead of repetitive tasks you can do things like LinePartsTemp[c("var1","var2")] <- lapply(LinePartsTemp[c("var1","var2")], as.integer) Also, if you provide a reproducible example with some simplified data, you will be much more likely to get an answer. Commented Mar 2, 2017 at 21:45
  • Thanks, I added some sample data and will look into lapply. Commented Mar 2, 2017 at 22:11

1 Answer 1

1

Consider interacting with lists which avoids initializing empty containers and later appending to them using numerous, separate environment objects. Below only two objects are used in addition to inputs.

  1. First, build a list of LineParts dataframes, LineParts_dfList
  2. Then, extract the needed data points into list of vectors, stations_veclist.

You will notice the dataframe list's lapply uses the <<- operator to update global objects (outside scope of local function) since LineParts needs to be reused with updated values:

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))
  )

And to avoid the many vapply calls, consider binding all LineParts dataframe items into one large dataframe, LinePartsAll (N=93,600 obs for 234 X 400), and then extract values sequentially by rows:

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']
  )

And to check, this updated, much faster method does repoduce same end values as original double for loop process. To test with posted sample data, you must set sample seed, set.seed(###), prior to both parts and LineParts assignment to rerun same random numbers:

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
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.