# setwd("C:/Users/nwickelmaier/Nextcloud/Documents/MDS/2023ss/60100_master_thesis/code") # Read data dat0 <- read.table("../data/rawdata_logfiles_small.csv", sep = ";", header = TRUE) dat0$date <- as.POSIXct(dat0$date) dat0$glossar <- ifelse(dat0$artwork == "glossar", 1, 0) # remove irrelevant events dat <- subset(dat0, !(dat0$event %in% c("Start Application", "Show Application"))) # Close move events close_moves <- function(data) { # close move events dat1 <- data[data$event %in% c("Transform start", "Transform stop"), ] dat1 <- dat1[order(dat1$artwork, dat1$date), ] num_start <- diff(c(0, which(dat1$event == "Transform stop"))) dat1$eventId <- rep(seq_along(num_start), num_start) # remove duplicated "Transform start" events dat1 <- dat1[!duplicated(dat1[, c("event", "eventId")]), ] # remove duplicated "Transform stop" events id_stop <- which(dat1$event == "Transform stop") id_rm_stop <- id_stop[diff(id_stop) == 1] dat1 <- dat1[-(id_rm_stop + 1), ] # transform to wide data format dat1$time <- ifelse(dat1$event == "Transform start", "start", "stop") trans_wide <- reshape(dat1, direction = "wide", idvar = c("eventId", "artwork", "glossar"), timevar = "time", drop = c("popup", "topicNumber", "event") ) trans_wide$event <- "move" trans_wide$eventId <- NULL trans_wide$duration <- trans_wide$timeMs.stop - trans_wide$timeMs.start trans_wide$distance <- apply( trans_wide[, c("x.start", "y.start", "x.stop", "y.stop")], 1, function(x) dist(matrix(x, 2, 2, byrow = TRUE))) trans_wide$rotationDegree <- trans_wide$rotation.stop - trans_wide$rotation.start trans_wide$scaleSize <- trans_wide$scale.stop / trans_wide$scale.start trans_wide$trace <- NA trans_wide$topicNumber <- NA trans_wide$popup <- NA dat_trans <- trans_wide[trans_wide$distance != 0 & trans_wide$rotationDegree != 0 & trans_wide$scaleSize != 1, c("fileId.start", "fileId.stop", "event", "artwork", "trace", "glossar", "date.start", "date.stop", "timeMs.start", "timeMs.stop", "duration", "topicNumber", "popup", "x.start", "y.start", "x.stop", "y.stop", "distance", "scale.start", "scale.stop", "scaleSize", "rotation.start", "rotation.stop", "rotationDegree")] rownames(dat_trans) <- NULL cat(paste("INFORMATION:", nrow(trans_wide) - nrow(dat_trans), "lines containing move events were removed since they did", "\nnot contain any change"), fill = TRUE) dat_trans } dat1 <- close_moves(dat) # TODO: Integrate this function into close_events? ########################################################################### # Add trace variable add_trace <- function(data) { dat2 <- data[!data$event %in% c("Transform start", "Transform stop"), ] dat2$trace <- NA last_event <- dat2$event[1] aws <- unique(dat2$artwork)[unique(dat2$artwork) != "glossar"] # for (art in aws) { # select artwork for (i in 1:nrow(dat2)) { # go through rows if (last_event == "Show Info" & dat2$artwork[i] == art) { dat2$trace[i] <- i j <- i } else if (last_event == "Show Front" & dat2$artwork[i] == art) { dat2$trace[i] <- j } else if (!(last_event %in% c("Show Info", "Show Front")) & dat2$artwork[i] == art) { dat2$trace[i] <- j } if (i <= nrow(dat2)) { last_event <- dat2$event[i + 1] } } } dat2 } add_trace2 <- function(data, glossar_dict = "../data/glossar_dict.RData") { data$trace <- NA dat1 <- data[data$event %in% c("Transform start", "Transform stop"), ] dat2 <- data[!data$event %in% c("Transform start", "Transform stop"), ] last_event <- dat2$event[1] aws <- unique(dat2$artwork)[unique(dat2$artwork) != "glossar"] # for (art in aws) { # select artwork for (i in 1:nrow(dat2)) { # go through rows if (last_event == "Show Info" & dat2$artwork[i] == art) { dat2$trace[i] <- i j <- i } else if (last_event == "Show Front" & dat2$artwork[i] == art) { dat2$trace[i] <- j } else if (!(last_event %in% c("Show Info", "Show Front")) & dat2$artwork[i] == art) { dat2$trace[i] <- j } if (i <= nrow(dat2)) { last_event <- dat2$event[i + 1] } } } glossar_files <- unique(dat2[dat2$artwork == "glossar", "popup"]) # load lookup table for artworks and glossar files load(glossar_dict) lut <- glossar_dict[glossar_dict$glossar_file %in% glossar_files, ] head(dat2[, c("artwork", "event", "popup", "trace")], 20) inside <- glossar_files[glossar_files %in% lut[sapply(lut$artwork, length) == 1, "glossar_file"]] single_art <- unlist(lut[lut$glossar_file %in% inside, "artwork"]) for (file in lut$glossar_file) { artwork_list <- unlist(lut[lut$glossar_file == file, "artwork"]) for (i in seq_len(nrow(dat2))) { if (dat2$event[i] == "Show Info" | (dat2$event[i] == "Artwork/OpenCard" & dat2$artwork[i] %in% single_art)) { current_artwork <- dat2[i, "artwork"] j <- i k <- i } else { current_artwork <- current_artwork } if (dat2$event[i] == "Show Front" & dat2$artwork[i] == current_artwork) { # make sure artwork has not been closed, yet! k <- i } if (dat2$artwork[i] == "glossar" & (current_artwork %in% artwork_list) & dat2$popup[i] == file & (j - k == 0)) { dat2[i, "trace"] <- dat2[j, "trace"] dat2[i, "artwork"] <- current_artwork } } } cat(proportions(table(is.na(dat2[dat2$glossar == 1, "trace"]))), fill = TRUE) out <- rbind(dat1, dat2) out <- out[order(out$fileId, out$date, out$timeMs), ] out } tmp <- add_trace2(dat) ########################################################################### close_events <- function(data, event = c("flipCard", "openTopic", "openPopup")) { if (event == "flipCard") { subdata <- subset(data, data$event %in% c("Show Info", "Show Front")) subdata$time <- ifelse(subdata$event == "Show Info", "start", "stop") subdata$eventId <- NA idvar <- c("trace", "artwork", "glossar") drop <- c("popup", "topicNumber") } else if (event == "openTopic") { subdata <- subset(data, data$event %in% c("Artwork/OpenCard", "Artwork/CloseCard")) subdata$time <- ifelse(subdata$event == "Artwork/OpenCard", "start", "stop") num_start <- diff(c(0, which(subdata$event == "Artwork/CloseCard"))) subdata$eventId <- rep(seq_along(num_start), num_start) idvar <- c("eventId", "trace", "glossar", "artwork", "topicNumber") drop <- "popup" } else if (event == "openPopup") { subdata <- subset(data, data$event %in% c("ShowPopup", "HidePopup")) subdata$time <- ifelse(subdata$event == "ShowPopup", "start", "stop") num_start <- diff(c(0, which(subdata$event == "HidePopup"))) subdata$eventId <- rep(seq_along(num_start), num_start) idvar <- c("eventId", "trace", "glossar", "artwork", "popup") drop <- "topicNumber" } data_wide <- reshape(subdata, direction = "wide", idvar = idvar, timevar = "time", drop = drop) data_wide$event <- event data_wide$duration <- data_wide$timeMs.stop - data_wide$timeMs.start for (d in drop) data_wide[d] <- NA data_wide$distance <- NA data_wide$scaleSize <- NA data_wide$rotationDegree <- NA out <- data_wide[, c("fileId.start", "fileId.stop", "event", "artwork", "trace", "glossar", "date.start", "date.stop", "timeMs.start", "timeMs.stop", "duration", "topicNumber", "popup", "x.start", "y.start", "x.stop", "y.stop", "distance", "scale.start", "scale.stop", "scaleSize", "rotation.start", "rotation.stop", "rotationDegree")] out # TODO: Suppress warnings? } tmp <- rbind(close_moves(dat), close_events(df, "flipCard"), close_events(df, "openTopic"), close_events(df, "openPopup")) # 'data.frame': 38607 obs. of 24 variables: # $ fileId.start : chr "2016_11_15-12_32_57.log" "2016_11_15-14_42_57.log" "2016_11_15-14_42_57.log" "2016_11_16-12_31_32.log" ... # $ fileId.stop : chr "2016_11_15-12_32_57.log" "2016_11_15-14_42_57.log" "2016_11_15-14_42_57.log" "2016_11_16-12_31_32.log" ... # $ event : chr "move" "move" "move" "move" ... # $ artwork : chr "001" "001" "001" "001" ... # $ trace : int NA NA NA NA NA NA NA NA NA NA ... # $ glossar : num 0 0 0 0 0 0 0 0 0 0 ... # $ date.start : POSIXct, format: "2016-12-15 12:39:49" "2016-12-15 14:49:37" ... # $ date.stop : POSIXct, format: "2016-12-15 12:39:49" "2016-12-15 14:49:40" ... # $ timeMs.start : int 412141 400777 554506 384312 406277 533864 548467 549396 158632 194982 ... # $ timeMs.stop : int 412474 403784 556633 388313 407994 538185 549088 551116 160343 197099 ... # $ duration : int 333 3007 2127 4001 1717 4321 621 1720 1711 2117 ... # $ topicNumber : int NA NA NA NA NA NA NA NA NA NA ... # $ popup : chr NA NA NA NA ... # $ x.start : num 531 235 470 326 326 ... # $ y.start : num 1221 734 2090 747 747 ... # $ x.stop : num 513 360 1492 256 2459 ... # $ y.stop : num 1212 809 1687 643 1430 ... # $ distance : num 19.8 146.6 1098.5 125.2 2239.4 ... # $ scale.start : num 0.8 0.301 0.8 0.301 0.301 ... # $ scale.stop : num 0.8 0.331 0.822 0.391 0.397 ... # $ scaleSize : num 1 1.1 1.03 1.3 1.32 ... # $ rotation.start: num 116 116 90 116 116 ... # $ rotation.stop : num 116.3 89.6 2.8 86.1 125.8 ... # $ rotationDegree: num 0.00245 -26.72397 -87.19711 -30.14456 9.49951 ...