-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathThreadNet_Metrics.R
More file actions
132 lines (116 loc) · 4.58 KB
/
Copy pathThreadNet_Metrics.R
File metadata and controls
132 lines (116 loc) · 4.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
##########################################################################################################
# THREADNET: Metrics
# This software may be used according to the terms provided in the
# GNU General Public License (GPL-3.0) https://opensource.org/licenses/GPL-3.0?
# Absolutely no warranty!
##########################################################################################################
# Functions for metrics: entropy, complexity, routine-ness, etc.
# takes the output from the function that maps threads to networks
#' Estimates the number of paths in a directed graph
#'
#' This function takes a network descripts (nodes and edges, as generaged by the functino threads_to_network, and estimates the number of paths.
#' as described in Haerem, Pentland and Miller (2015). The estimate correlates with the McCabe's (1975) cyclometric complexity.
#'
#' @family ThreadNet_Metrics
#'
#' @param net
#'
#' @return number
#' @export
#'
#' @examples
estimate_network_complexity <- function(net){ return(estimate_task_complexity_index( nrow(net$nodeDF), nrow(net$edgeDF)) ) }
# this version takes vertices and edges
#' Estimates the number of paths in a directed graph
#'
#' Same as estimate_network_complexity, but takes different parameters
#'
#' @family ThreadNet_Metrics
#'
#' @param v number of vertices (or nodes)
#' @param e number of edges
#'
#' @return number
#' @export
estimate_task_complexity_index <- function(v,e){
#INPUT ARGS:
# in MatLab version, arguments were v (vertices) and e (edges)
# v = number of vertices
# tested for range of 10 < v < 100
# e = number of edges
# print("edges")
# print(e)
# print("vertices")
# print(v)
#
# OUTPUT ARG:
# cidx correlates with Log10(simple paths) with r>= 0.8
# from ORM paper analysis, constant is 0.12.
# For boundary condition of 2 nodes and 1 edge, complexity index=0, constant = 0.08
return( 0.08 + 0.08*e - 0.08*v )
}
#################################################################
#' Computes a metric of routineness based on frequency of ngrams
#'
#' Computes the fraction of observed behavior that conforms to an observed pattern.
#' Current version uses ngrams, but it would be good to use spmf pattern mining to avoid including duplicate patterns (e.g., a-b-c and b-c-d)
#'
#' @family ThreadNet_Metrics
#'
#' @param o data frame with occurresnces or events
#' @param TN name of column with threadNumbers
#' @param CF name of column with contextual factor
#' @param n size of ngram
#' @param m how many of the most frequent ngrams to include. When m > 1, there is a risk of duplication.
#'
#' @return number, index of routineness.
#'
#' @export
routineness_metric <- function(o,TN,CF,n,m){
# get the ngrams
ng=count_ngrams(o,TN,CF,n)
# print(ng[1:m,])
# return the ratio of occurrences in the top m most frequent ngrams to total occurrences
return( sum(ng$freq[1:m])*n/nrow(o) )
}
#############################################################################
#' Computes the compressibility of the data in one column of a data frame
#'
#' Compressibility is an index of complexity -- more compressible means less complex. This function computes the ratio of compressed data
#' to the original data. Should be between zero and one. Uses built-in functions for in=memory compression
#'
#' @family ThreadNet_Metrics
#'
#' @param df a data frame containing occurrences or events
#' @param CF a column or contextual factor in that data frame
#'
#' @return number containing compressibility index, 0 < i < 1
#' @export
compression_index <- function(df,CF){ return(
length(memCompress(paste0(as.character(df[[CF]])),type="gzip")) /
length(paste0(as.character(df[[CF]]))) ) }
#######################################################################
#compute entropy for a set of observations in a column from a data frame
# freq is typically going to the $freq column from ngram table, or
# the frequency of each level in the CFs, as counted by table()
#' Compute the entropy of a contextual factor
#'
#' Each column in the raw data represents a contextual factor. This function computes the entropy of each factor that is selected for use in the
#' analysis.
#' @family ThreadNet_Metrics
#'
#' @param freq is the frequency distribution of the levels in the factor
#'
#' @return number
#' @export
compute_entropy <- function(freq){
N = sum(freq)
p = freq/N
plnp = p*log(p)
return(-sum(plnp))
}
# code to plot entropy as a function of zoom_level
# need to get the zoom levels -- grep out the 'Z_' column names...
plot_entropy <- function(e){
plot(unlist(lapply(grep('ZM_',colnames(e)),function(i){compute_entropy(table(e[[i]]))})))
}