summaryrefslogtreecommitdiffstats
path: root/admin/survey/modules/mod_SPEEDINDEX
diff options
context:
space:
mode:
Diffstat (limited to 'admin/survey/modules/mod_SPEEDINDEX')
-rw-r--r--admin/survey/modules/mod_SPEEDINDEX/R/speeder_index.R98
-rw-r--r--admin/survey/modules/mod_SPEEDINDEX/class.SurveySpeedIndex.php204
2 files changed, 302 insertions, 0 deletions
diff --git a/admin/survey/modules/mod_SPEEDINDEX/R/speeder_index.R b/admin/survey/modules/mod_SPEEDINDEX/R/speeder_index.R
new file mode 100644
index 0000000..f41ef2f
--- /dev/null
+++ b/admin/survey/modules/mod_SPEEDINDEX/R/speeder_index.R
@@ -0,0 +1,98 @@
+params <- commandArgs(trailingOnly = TRUE)
+ID <- params[1]
+
+library(foreign) # Import csv or sav data
+
+#########################
+# SPEEDER INDEX FUNKCIJA
+#########################
+# funkcija je napisana s for zankami, da je lazje razumljivo, sicer pa je to počansejši način, zato ce bos popravljal
+# raje uporabi apply ali by ali kaj podobnega
+speeder <- function(data){
+ # izracuna mediane po stolpcih
+ medians <- apply(X = data, 2, median, na.rm=T)
+ # naredi novo matriko enakih dimenizij, kot je orig. podatkovna matrika
+ news <- matrix(NA, nrow = dim(data)[1], ncol = dim(data)[2])
+
+ # gre cez vse enote
+ for (i in 1:dim(data)[1]){
+ for (j in 1:dim(data)[2]){
+ # ce je manjkajoca vrednost ne naredi nic
+ if (is.na(data[i,j]) == T) {news[i,j] <- NA}
+ if (is.na(data[i,j]) == F){
+ # ce je vrednost pri enoti vecja ali enaka od mediane potem ji pripise 1
+ if (data[i,j] >= medians[j]){news[i,j] <- 1}
+ # ce je vrednost pri enoti manjsa, ji pripise vrednost pri enoti deljeno z vrednostjo mediane odgovarajaoce spr.
+ if (data[i,j] < medians[j]){news[i,j] <- (data[i,j]/medians[j])}
+ }
+ }
+ }
+
+ # izracuna povprecja (tocka 3 v algoritmu)
+ povprecja <- rowMeans(news, na.rm=T)
+ # ce je pod 10 procentov vseh, potem je speeder
+ speed_no_speed <- as.numeric(povprecja < quantile(povprecja, 0.1))
+ speed_no_speed[speed_no_speed == 1] <- "1"
+ speed_no_speed[speed_no_speed == 0] <- "0"
+ return(speed_no_speed)
+}
+## //SPEEDER INDEX FUNKCIJA// ##
+
+
+
+# Preberemo vhodne podatke
+datumi <- read.csv2(paste0("modules/mod_SPEEDINDEX/temp/datum", ID, ".csv"), sep=";", header = T, fill = T, stringsAsFactors = FALSE)
+#if (datumi[1,1]=="Ustreznost") {datumi <- datumi[2:nrow(datumi),]}
+datumi <- subset(datumi, Status==6)
+
+## SELECT APROPRIATE DATA ##
+# Iz baze izberemo le stolpce, ki nas zanimajo: Vse stolpce, ki v imenu vsebujejo Datum (ker računamo čase na strani) ter Id = RECNUM
+test <- datumi[ ,grepl("Datum|Id" , names( datumi ) ) ]
+
+# Izberemo le stolpce, ki vsebujejo več kot 10 znakov zato, ker so bile nekje v stolpcih vrednosti 0 ali 1
+#test <- test[apply(test, MARGIN = 1, function(x) all(nchar(x) > 10)), ]
+
+# Zapišemo RECNUm oz. ID
+test_id <- test[1]
+
+
+# Počistimo še DATUM in izberemo le URO
+test <- apply(test[2:ncol(test)], 2, function(y) gsub(".* ", "", y))
+test <- test[ , ! apply( test , 2 , function(x) all(is.na(x)) ) ]
+# Če so na straneh prazne vrednosti, prepišemo vrednosti iz prejšnjega stolpca
+#test <- ifelse(test=="", test[,-1], test)
+## //SELECT APROPRIATE DATA// ##
+
+
+
+# čas v sekundah, ki ga je anketiranec preživel na x strani (ki se izračuna kot razlika med stolpcem date_x in date_x+1)
+makeTime <- function(x) as.POSIXct(paste(Sys.Date(), x))
+dat <- apply(test, 2, makeTime)
+data <- mapply(x = 2:ncol(dat),
+ y = 1:(ncol(dat) -1),
+ function(x, y) dat[ , x] - dat[ , y])
+
+
+
+
+# data <- read.spss("speederindex.sav", to.data.frame = T)
+data <- as.matrix(data)
+# Poženemo funkcijo speeder index na podatkih
+#speeder(data)
+speederindex <- speeder(data)
+# Indeksu dodamo čase respondentov po straneh
+speederindex <- cbind(speederindex, data)
+
+df <- speederindex
+
+colnames(df)[1] <- "Index hitrosti"
+
+for(i in 2:ncol(df)){
+ colnames(df)[i] <- paste0("Stran ", i-1)
+}
+
+df <- cbind(test_id,df)
+
+# Zapišemo rezultat v csv
+write.csv2(df, paste0("modules/mod_SPEEDINDEX/results/speederindex", ID, ".csv"),row.names=F)
+#write.csv2(speederindex, file ="modules/mod_SPEEDINDEX/results/speederindex.csv",row.names=T)
diff --git a/admin/survey/modules/mod_SPEEDINDEX/class.SurveySpeedIndex.php b/admin/survey/modules/mod_SPEEDINDEX/class.SurveySpeedIndex.php
new file mode 100644
index 0000000..87a1e8b
--- /dev/null
+++ b/admin/survey/modules/mod_SPEEDINDEX/class.SurveySpeedIndex.php
@@ -0,0 +1,204 @@
+<?php
+
+define("TEMP_FOLDER", "admin/survey/modules/mod_SPEEDINDEX/temp");
+define("SCRIPT_FOLDER", "admin/survey/modules/mod_SPEEDINDEX/R");
+define("RESULTS_FOLDER", "admin/survey/modules/mod_SPEEDINDEX/results");
+
+class SurveySpeedIndex{
+
+ var $anketa; # id ankete
+ var $db_table = '';
+
+
+ function __construct($anketa){
+ global $site_url;
+
+ // Ce imamo anketo, smo v status->ul evealvacija
+ if ((int)$anketa > 0){
+ $this->anketa = $anketa;
+
+ # polovimo vrsto tabel (aktivne / neaktivne)
+ SurveyInfo :: getInstance()->SurveyInit($this->anketa);
+ if (SurveyInfo::getInstance()->getSurveyColumn('db_table') == 1) {
+ $this->db_table = '_active';
+ }
+ }
+ }
+
+
+ // PrikaĹľemo stran
+ public function displaySpeedIndex(){
+ global $lang;
+
+ // Izvedemo pripravo datoteke
+ $this->executeExport();
+
+ // Izrisemo tabelo
+ $this->displaySpeedIndexTable();
+ }
+
+ // Prikazemo tabelo
+ private function displaySpeedIndexTable(){
+ global $site_path;
+ global $lang;
+
+ $result_folder = $site_path . RESULTS_FOLDER.'/';
+
+ echo '<div id="speeder_table">';
+
+ echo '<span class="bold">'.$lang['srv_speeder_index_text'].'</span>';
+
+ // Legenda
+ echo '<div class="speeder_leg">';
+ echo '<span class="speeder_legend spaceLeft spaceRight" style="background-color:#ffffff;">'.$lang['srv_speeder_index_legend_0'].'</span>';
+ echo '<span class="speeder_legend spaceLeft" style="background-color:#ffe8e8;">'.$lang['srv_speeder_index_legend_1'].'</span>';
+ echo '</div>';
+
+ echo '<table id="tbl_speeder">';
+
+ if (($handle = fopen($result_folder."speederindex".$this->anketa.".csv", "r")) !== FALSE) {
+ // Loop po vrsticah
+ $cnt=0;
+ while (($row = fgetcsv($handle, 1000, ';')) !== FALSE) {
+
+ $status = ($row[1] == 1 ? 'speeder' : 'no_speeder');
+
+ echo '<tr class="'.$status.'">';
+
+ // Prva vrstica
+ if($cnt == 0){
+ foreach($row as $val){
+ echo '<th>';
+
+ // Prevedemo kar na roko:)
+ if($lang['id'] == '2'){
+ if($val == 'Index hitrosti')
+ echo $lang['srv_speeder_index'];
+ else
+ echo str_replace("Stran", $lang['page'], $val);
+ }
+ else
+ echo $val;
+
+ echo '</th>';
+ }
+ }
+ // Vrstice s podatki
+ else{
+ foreach($row as $val){
+ echo '<td>';
+ echo $val;
+ echo '</td>';
+ }
+ }
+
+ echo '</tr>';
+
+ $cnt++;
+ }
+ fclose($handle);
+ }
+
+ echo '</table></div>';
+ }
+
+
+ // Zgeneriramo pdf analizo
+ public function executeExport(){
+ global $site_path;
+ global $lang;
+ global $admin_type;
+
+ // Zgeneriramo zacasne csv datoteke
+ $this->prepareCSV();
+
+ // Poklicemo R skripto in zgeneriramo pdf
+ $script = $site_path . SCRIPT_FOLDER . '/speeder_index.R';
+ $out = exec('Rscript '.$script.' '.$this->anketa.' 2>&1', $output, $return_var);
+
+ // Testiranje - izpis errorjev
+ /*if($admin_type == 0){
+ echo '<div>';
+ echo 'Rscript '.$script;
+ //echo '<br />'.$out.'<br />';
+ var_dump($output);
+ echo '</div>';
+ }*/
+
+ // Na koncu pobrisemo zacasne datoteke
+ $this->deleteTemp();
+ }
+
+ // Pripravi csv s podatki o casih po straneh
+ public function prepareCSV(){
+ global $site_path;
+ global $lang;
+ global $admin_type;
+
+ $temp_folder = $site_path . TEMP_FOLDER.'/';
+
+ $file_handler = fopen($temp_folder.'datum'.$this->anketa.'.csv',"w");
+
+
+ // Prva vrstica
+ $line_header = 'Id;Status;Lurker;Datum_0;';
+
+ $grupe = array();
+ $sql = sisplet_query("SELECT * FROM srv_grupa WHERE ank_id='".$this->anketa."' ORDER BY vrstni_red ASC");
+ while ($row = mysqli_fetch_array($sql)) {
+ $line_header .= 'Datum_'.$row['vrstni_red'].';';
+
+ $grupe[$row['id']] = $row['vrstni_red'];
+ }
+
+ fwrite($file_handler, substr($line_header, 0, -1)."\r\n");
+
+
+ // Vrstice s podatki
+ $sql = sisplet_query("SELECT id, recnum, last_status, lurker, time_insert FROM srv_user u
+ WHERE ank_id='".$this->anketa."' AND preview='0' AND deleted='0'
+ ORDER BY recnum ASC");
+ while ($row = mysqli_fetch_array($sql)) {
+
+ $line = $row['recnum'].';';
+ $line .= $row['last_status'].';';
+ $line .= $row['lurker'].';';
+ $line .= $row['time_insert'].';';
+
+ // Napolnimo case respondenta
+ $user_grupe = array();
+ $sqlG = sisplet_query("SELECT gru_id, time_edit FROM srv_user_grupa".$this->db_table."
+ WHERE usr_id='".$row['id']."'");
+ while ($rowG = mysqli_fetch_array($sqlG)) {
+ $user_grupe[$rowG['gru_id']] = $rowG['time_edit'];
+ }
+
+ // Sprehodimo se po vseh straneh in zapisemo case v vrstico
+ foreach($grupe as $gru_id => $vrstni_red){
+
+ if(isset($user_grupe[$gru_id]))
+ $line .= $user_grupe[$gru_id].';';
+ else
+ $line .= ';';
+ }
+
+ fwrite($file_handler, substr($line, 0, -1)."\r\n");
+ }
+
+
+ fclose($file_handler);
+ }
+
+ // Pobrisemo zacasne datoteke
+ private function deleteTemp(){
+ global $site_path;
+
+ $temp_folder = $site_path . TEMP_FOLDER.'/';
+
+ // Pobrisemo zacasno CSV datoteko s podatki
+ if (file_exists($temp_folder.'/datum'.$this->anketa.'.csv')) {
+ unlink($temp_folder.'/datum'.$this->anketa.'.csv');
+ }
+ }
+
+} \ No newline at end of file