Skip to content

Commit 357f9dd

Browse files
committed
New Excel output (close #6), update README, tweak UI (e.g. mouse-overs)
* Excel output: added table with raw matching score, i.e. without constructs reversal, to better resemble step 3 from method description * Update README with parts from the JOSS paper as suggested by reviewers * UI Tweaks to improve usability: info box informs that the output is an Excel file, mouser-over for most analysis settings * Added MIT License
1 parent 9af753f commit 357f9dd

File tree

12 files changed

+202
-117
lines changed

12 files changed

+202
-117
lines changed

DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Authors@R: c(person(
2121
Description: Shiny UI to identify cliques of related constructs in repertory grid data.
2222
See Burr, King, & Heckmann (2020) <doi:10.1080/14780887.2020.1794088> for a description
2323
of the interpretive clustering (IC) method.
24-
Version: 0.5.2
24+
Version: 0.6.0
2525
Date: 2022-04-24
2626
Imports:
2727
graphics,
@@ -59,4 +59,4 @@ Suggests:
5959
Encoding: UTF-8
6060
URL: https://github.com/markheckmann/OpenRepGrid.ic
6161
BugReports: https://github.com/markheckmann/OpenRepGrid.ic/issues
62-
RoxygenNote: 7.1.1
62+
RoxygenNote: 7.1.2

LICENSE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
YEAR: 2022
2+
COPYRIGHT HOLDER: OpenRepGrid.ic authors

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@ importFrom(dplyr,group_by)
2525
importFrom(dplyr,recode)
2626
importFrom(dplyr,select)
2727
importFrom(magrittr,"%>%")
28+
importFrom(shinyBS,tipify)
2829
importFrom(stats,na.omit)
2930
importFrom(withr,with_par)

NEWS.Rmd

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@ output: html_document
44
---
55

66

7-
## v0.5.2
7+
## v0.6.0
88

9+
* Excel output: added table with raw matching score, i.e. without constructs reversal, to better
10+
resemble step 3 from method description
11+
* Update README with parts from the JOSS paper as suggested by reviewers
12+
* UI Tweaks to improve usability: info box informs that the output is an Excel file,
13+
mouser-over for most analysis settings
914
* Added MIT License
1015

1116
## v0.5.1

R/02-calculate.R

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
#////////////////////////////////////////////////////////////
1+
#//////////////////////////////////////////////////////////////////////////////////////
22
#
3-
# IC Calculations
3+
# IC Calculations
44
#
5-
#////////////////////////////////////////////////////////////
5+
#//////////////////////////////////////////////////////////////////////////////////////
6+
67

78
#' Count number of matches / non-matches for two constructs
89
#'
@@ -92,10 +93,6 @@ calculate_similarity <- function(x, min_matches = 6, align_poles = TRUE) #, use_
9293
}
9394
}
9495

95-
# # for each construct geerate list of constructs constructs with >= 6 matches
96-
# mm <- apply(ii, 1, which) # like in Table 4a
97-
# # mx <- sapply(mm, length) %>% max
98-
9996
# keep bigger relatedness score
10097
M_vec <- as.vector(M)
10198
Mi_vec <- as.vector(Mi)
@@ -108,7 +105,7 @@ calculate_similarity <- function(x, min_matches = 6, align_poles = TRUE) #, use_
108105
# mark positive and negative relatedness
109106
ii_m <- M >= criterion_
110107
ii_mi <- Mi >= criterion_
111-
ii <- ii_m | ii_mi # min of 6 identical responses (match or mismatch)
108+
ii <- ii_m | ii_mi # min of n identical responses (match or mismatch)?
112109
D[ii_m] <- 1
113110
D[ii_mi] <- -1
114111

@@ -134,7 +131,8 @@ calculate_similarity <- function(x, min_matches = 6, align_poles = TRUE) #, use_
134131
names(valence_left) <- labels
135132
names(valence_right) <- labels
136133

137-
list(R = R, # no of matches
134+
list(R = R, # no of matches (indlucing optional construct reversal, i.e. only high no. of matches relevant
135+
M = M, # matrix of matches without optional construct reversal, as described in paper, i.e. a very low and very high number of matches relevant
138136
MM = MM, # relatedness 0/1
139137
D = D, # direction of relation -1/1
140138
constructs = constructs,
@@ -357,7 +355,7 @@ network_graph_images <- function(x,
357355

358356
img_all_constructs <- tempfile(fileext = ".png")
359357
png(img_all_constructs, width = 20, height = 20, units = "cm", res = 300)
360-
#par(oma = c(0,0,0,0), mar = c(0,0,0,0))
358+
#par(oma = c(0,0,0,0), mar = c(0,0,0,0)) # can be left out for now but kept as a reminder comment for an alternative approach
361359
with_par(img_par, {
362360
set.seed(seed)
363361
igraph::plot.igraph(g,
@@ -400,7 +398,7 @@ network_graph_images <- function(x,
400398

401399
img_all_constructs_full_labels <- tempfile(fileext = ".png")
402400
png(img_all_constructs_full_labels, width = 20, height = 20, units = "cm", res = 300)
403-
# par(oma = c(0,0,0,0), mar = c(0,0,0,0))
401+
# par(oma = c(0,0,0,0), mar = c(0,0,0,0)) # can be left out for now but kept as a reminder comment for an alternative approach
404402
with_par(img_par, {
405403
set.seed(seed)
406404
igraph::plot.igraph(g,
@@ -439,7 +437,6 @@ network_graph_images <- function(x,
439437
ii_keep <- match(cns, names(cnames))
440438
vertex.labels <-
441439
cnames[cns] %>%
442-
# str_sub(start = 1, end = label_max_length) %>%
443440
str_wrap(width = label_wrap_width)
444441
vertex.size <- 22
445442
vertex.label.cex <- .5
@@ -533,7 +530,7 @@ network_graph_images <- function(x,
533530
vertex.size = vertex.size,
534531
vertex.label = vertex.labels2,
535532
vertex.size2 = vertex.size,
536-
vertex.label.color = colors_poles_right, #"black",
533+
vertex.label.color = colors_poles_right,
537534
vertex.label.cex = vertex.label.cex,
538535
vertex.label.family = "mono",
539536
vertex.label.font = vertex_font_pole_2,
@@ -691,8 +688,8 @@ network_graph_images <- function(x,
691688
})
692689

693690
names(vertex_relations) <- cns
694-
vertex_font_pole_1 <- 1 #recode(vertex_relations, "neg"= 2, .default = 1)
695-
vertex_font_pole_2 <- 2 # recode(vertex_relations, "neg"= 1, .default = 2)
691+
vertex_font_pole_1 <- 1 # recode(vertex_relations, "neg"= 2, .default = 1) # can be left out for now but kept as a reminder comment for an alternative approach
692+
vertex_font_pole_2 <- 2 # recode(vertex_relations, "neg"= 1, .default = 2) # can be left out for now but kept as a reminder comment for an alternative approach
696693

697694
vertex.labels1 <- replace_all(vertex.labels, first = TRUE)
698695
vertex.labels2 <- replace_all(vertex.labels, first = FALSE)

R/03-excel.R

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
#////////////////////////////////////////////////////////////
1+
#/////////////////////////////////////////////////////////////////////////////////////
22
#
3-
# Excel output
3+
# Excel output
44
#
5-
#////////////////////////////////////////////////////////////
5+
#/////////////////////////////////////////////////////////////////////////////////////
66

77

88
#' Check if Excel input file contains valid data
@@ -149,7 +149,8 @@ create_excel_output <- function(file, data = list())
149149
nms <- names(wb)
150150
constructs_df <- data.frame("constructs" = data$constructs, stringsAsFactors = FALSE)
151151
R <- data$R
152-
D <- data$D
152+
D <- data$D # matrix with matches (with optional construct reversal)
153+
M <- data$M # matrix with matches (no construct reversal)
153154
cliques_list <- data$cliques_list
154155
clique_lists_full_names <- data$clique_lists_full_names
155156

@@ -202,10 +203,20 @@ create_excel_output <- function(file, data = list())
202203
c("* Positive construct poles (as indicated by column 'preferred') are aligned on the right",
203204
"** 1 = positive relatedness, -1 = negative relatedness"), stringsAsFactors = FALSE)
204205
writeData(wb, sheet, lgnd, startRow = row + 2, startCol = 1, colNames = FALSE, rowNames = FALSE)
205-
206-
# matches
206+
207+
# matches (no construct reversal)
207208
row <- 6
208-
writeData(wb, sheet, "Number of matches between constructs*", startRow = row, startCol = 1)
209+
writeData(wb, sheet, "Number of matches between constructs (no construct reversal)*", startRow = row, startCol = 1)
210+
addStyle(wb, sheet, style = style_bold, gridExpand = TRUE, rows = row, cols = 1)
211+
writeData(wb, sheet, constructs_df, startRow = row + 2, startCol = 1, colNames = TRUE, rowNames = FALSE)
212+
addStyle(wb, sheet, style = style_right, rows = row + 2, cols = 1)
213+
addStyle(wb, sheet, style = style_italic, rows = row + 2, cols = 1, stack = TRUE)
214+
addStyle(wb, sheet, style = style_right, gridExpand = TRUE, rows = 1L:nrow(R) + row + 2, cols = 1)
215+
writeData(wb, sheet, M, startRow = row + 2, startCol = 2, colNames = TRUE, rowNames = TRUE)
216+
217+
# matches (with optional construct reversal)
218+
row <- row + nrow(M) + 4
219+
writeData(wb, sheet, "Number of matches between constructs (after optional construct reversal)*", startRow = row, startCol = 1)
209220
addStyle(wb, sheet, style = style_bold, gridExpand = TRUE, rows = row, cols = 1)
210221
writeData(wb, sheet, constructs_df, startRow = row + 2, startCol = 1, colNames = TRUE, rowNames = FALSE)
211222
addStyle(wb, sheet, style = style_right, rows = row + 2, cols = 1)
@@ -215,7 +226,7 @@ create_excel_output <- function(file, data = list())
215226

216227
# direction
217228
i <- row + nrow(R) + 4
218-
txt <- paste0("Relatedness by criterion (matches >= ", min_matches, ")**")
229+
txt <- paste0("Relatedness by criterion (matches >= ", min_matches, " after optional construct reversal)**")
219230
writeData(wb, sheet, txt, startRow = i, startCol = 1)
220231
addStyle(wb, sheet, style = style_bold, gridExpand = TRUE, rows = i, cols = 1)
221232
writeData(wb, sheet, constructs_df, startRow = i + 2, startCol = 1, colNames = TRUE, rowNames = FALSE)
@@ -228,6 +239,7 @@ create_excel_output <- function(file, data = list())
228239
conditionalFormatting(wb, sheet, cols = 1L:nrow(R) + 2, rows = 1L:nrow(R) + i + 2, rule = "<0", style = neg_style)
229240
conditionalFormatting(wb, sheet, cols = 1L:nrow(R) + 2, rows = 1L:nrow(R) + i + 2, rule = ">0", style = pos_style)
230241

242+
231243
# Clique enumeration ----------------------------------
232244

233245
sheet <- "cliques"

R/OpenRepGrid.ic.R

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#' @rawNamespace import(graphics, except = box)
3434
#' @importFrom withr with_par
3535
#' @importFrom stats na.omit
36+
#' @importFrom shinyBS tipify
3637
#' @import
3738
#' utils
3839
#' grDevices

README.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,31 @@ This package implements the [Interpretive Clustering (IC)](https://doi.org/10.10
1010
method as described in [Burr, King, and Heckmann (2020)](https://doi.org/10.1080/14780887.2020.1794088).
1111
An introduction to the software is available on [YouTube](https://youtu.be/f9oINYA22Rc).
1212
Interpretive Clustering is a variant of construct clustering for [repertory grid](https://en.wikipedia.org/wiki/Repertory_grid)
13-
data. While derived from theoretical considerations based on [Personal Construct Theory](https://en.wikipedia.org/wiki/Personal_construct_theory), the procedure itself is mathematically equivalent to a problem from graph theory called [maximal cliques enumeration](https://en.wikipedia.org/wiki/Clique_problem#Listing_all_maximal_cliques). Given a similarity measure, in our case the number of matching scores between two constructs, a network graph of relatedness between constructs is construed. A clique is a group of constructs which are all mutually related, given some cut-off criterion for relatedness (e.g. 6 matching scores in a grid with 7 elements). While an offline approach is also described to find the construct cliques, this software automates the process. Below you see the resulting cliques for Sylvia's sample grid. In the paper, the interpretation of the discovered cliques is discussed in detail.
13+
data. While derived from theoretical considerations based on [Personal Construct Theory](https://en.wikipedia.org/wiki/Personal_construct_theory), the procedure itself is mathematically equivalent to a problem from graph theory called [maximal cliques enumeration](https://en.wikipedia.org/wiki/Clique_problem#Listing_all_maximal_cliques).
14+
Given a similarity measure, in our case the number of matching scores between
15+
two constructs, a network graph of relatedness between constructs is construed.
16+
A clique is a group of constructs which are all mutually related, given some
17+
cut-off criterion for relatedness (e.g. 6 matching scores in a grid with 7
18+
elements). While an offline approach is also described to find the construct
19+
cliques, this software automates the process. Below you see the resulting
20+
cliques for Sylvia's sample grid. In the paper, the interpretation of the
21+
discovered cliques is discussed in detail.
1422

1523
![example](inst/shiny/www/sylvia_cliques.png "Construct cliques for Sylvias's grid")
1624

1725

26+
# Statement of need
27+
28+
Currently, the IC method is not implemented in any other existing repertory grid
29+
software. While IC can also be conducted by hand, this is very time consuming,
30+
error-prone and only feasible for small-sized grids. Hence, a software solution
31+
to support the IC procedure is needed. Without proper software support which
32+
facilitates the process, the IC method is likely to become a methodological
33+
contribution which will rarely be used in research due to above mentioned
34+
reasons.
35+
36+
37+
1838
## Installation
1939

2040
You can install the latest official release version from CRAN
@@ -44,3 +64,12 @@ You can find the datasets used in our publication on Zenodo.
4464

4565
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.3629868.svg)](https://doi.org/10.5281/zenodo.3629868)
4666

67+
68+
# Contributing
69+
70+
In order to maximize the package's usefulness for the research community, we
71+
welcome participation in the package's development. Experienced R programmers
72+
are asked to make pull requests to the [`OpenRepGrid.ic` github repository](https://github.com/markheckmann/OpenRepGrid.ic), [report issues](https://github.com/markheckmann/OpenRepGrid.ic/issues), or commit code
73+
snippets. Non-technical oriented researchers are invited to send us feature
74+
requests or suggestions for improvement.
75+

inst/examples/01-process-excel-file.R

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ l <- network_graph_images(x, min_clique_size = 3,
1515
show_edges = TRUE,
1616
min_matches = 6) # produce images
1717
file_tmp <- create_excel_output(file, l) # create Excel file
18-
19-
# copy Excel to working dir (commented out to avoid file generation during testing)
20-
#file.copy(file_tmp, file_out, overwrite = TRUE)
18+
# file.show(file_tmp) # not run during tests
2119

2220
# open images saved as temp files (as shown in output Excel file)
2321
file.show(l$img_all_constructs)

inst/shiny/server.R

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
#////////////////////////////////////////////////////
1+
#///////////////////////////////////////////////////////////////////////////////////////////
22
#
3-
# server
3+
# server
44
#
5-
#////////////////////////////////////////////////////
5+
#//////////////////////////////////////////////////////////////////////////////////////////
66

77
library(shiny)
88
library(shinyjs)
@@ -100,7 +100,6 @@ server <- function(input, output, session)
100100
# the flag 'data_status' is needed so other processes can use the info
101101
observeEvent(rv$data, {
102102
x <- rv$data
103-
cat("\ncheck data")
104103
if (is.null(x)) {
105104
rv$data_status <- "empty"
106105
} else {
@@ -196,7 +195,6 @@ server <- function(input, output, session)
196195
# all test were passed
197196
cat("\nall tests passed")
198197
hide("error_box")
199-
show("success_box")
200198
show("down_btn")
201199
show("settings_box_1")
202200
show("settings_box_2")

0 commit comments

Comments
 (0)