patternpythonMinor
Imperative code in R keeping track of state
Viewed 0 times
keepingtrackimperativestatecode
Problem
A friend of mine has a spreadsheet where she coded a classroom video for various teaching events, which I needed to help her plot. For each recording, she used several video cassettes, and her time codes were relative to each video cassette (ie. they always start on 0). To be able to plot these on a timeline, I needed to convert the times into a relative (continuous) time. The code below works perfectly (and I've solved the problem), however it doesn't look good to me. It looks like the code I used to write in Ruby, before I began playing with R, Haskell etc.
This is not the first time I've come across this kind of a problem - iterating through rows, or lines of text, needing to keep track of several different kinds of "state", etc. I would be curious if this code could be rewritten to look cleaner, more idiomatic.
Example dataset
Example code
1 KK-NoZZ alfred1.mov alfred's class 0 2 0 2 0
2 FBP alfred1.mov alfred's class 2 4 2 4 0
3 CC-NoZZ alfred1.mov alfred's class 6 8 6 8 0
4 CC-NoZZ alfred2.mov alfred's class 0 4 8
This is not the first time I've come across this kind of a problem - iterating through rows, or lines of text, needing to keep track of several different kinds of "state", etc. I would be curious if this code could be rewritten to look cleaner, more idiomatic.
Example dataset
structure(list(code = structure(c(4L, 3L, 1L, 1L, 5L, 4L, 3L,
1L, 5L, 2L), .Label = c("CC-NoZZ", "CC-ZZ", "FBP", "KK-NoZZ",
"KK-ZZ"), class = "factor"), src = structure(c(1L, 1L, 1L, 2L,
2L, 3L, 3L, 4L, 4L, 4L), .Label = c("alfred1.mov", "alfred2.mov",
"claire1.mov", "claire2.mov"), class = "factor"), class = structure(c(1L,
1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L), .Label = c("alfred's class",
"claire's class"), class = "factor"), start = c(0L, 2L, 6L, 0L,
10L, 1L, 5L, 0L, 6L, 14L), end = c(2L, 4L, 8L, 4L, 12L, 3L, 9L,
4L, 10L, 20L)), .Names = c("code", "src", "class", "start", "end"
), class = "data.frame", row.names = c(NA, -10L))
Example code
src = ""
class = ""
delta = 0
db$corr.start = NA
db$corr.end = NA
db$delta = NA
for(i in 1:nrow(db)) {
row
Example output
code src class start end corr.start corr.end delta1 KK-NoZZ alfred1.mov alfred's class 0 2 0 2 0
2 FBP alfred1.mov alfred's class 2 4 2 4 0
3 CC-NoZZ alfred1.mov alfred's class 6 8 6 8 0
4 CC-NoZZ alfred2.mov alfred's class 0 4 8
Solution
R encourages vector-based operations instead of loops. But in this case, I don't think there's a good way around tracking the state of
This might be a slightly better way to create a vector
Based on
delta. This might be a slightly better way to create a vector
delta:delta <- 0
vdelta <- c(0)
for (i in 2:nrow(db)) {
row <- db[i,]
prev <- db[i-1,]
if (row$class != prev$class) {
delta <- 0
} else if (row$src != prev$src) {
delta <- prev$end + delta
}
vdelta <- c(vdelta, delta)
}Based on
vdelta you can easily create the columns you need:db$corr.start <- db$start + vdelta
db$corr.end <- db$end + vdelta
db$delta <- vdeltaCode Snippets
delta <- 0
vdelta <- c(0)
for (i in 2:nrow(db)) {
row <- db[i,]
prev <- db[i-1,]
if (row$class != prev$class) {
delta <- 0
} else if (row$src != prev$src) {
delta <- prev$end + delta
}
vdelta <- c(vdelta, delta)
}db$corr.start <- db$start + vdelta
db$corr.end <- db$end + vdelta
db$delta <- vdeltaContext
StackExchange Code Review Q#51910, answer score: 2
Revisions (0)
No revisions yet.