All tables

Here are the figures from the paper Art of the Brainwaves.

data

Code
data <- read_excel("../data/results_survey.xlsx")
data <- data[1:121] %>% 
  filter(.[[18]] !='Yes') # not analysed any EEG method

n1 <- readxl::read_xlsx("../data/aggregated_plotnames.xlsx", sheet = 1)
n2 <- readxl::read_xlsx("../data/aggregated_plotnames.xlsx", sheet = 2)
n3 <- readxl::read_xlsx("../data/aggregated_plotnames.xlsx", sheet = 3)
n4 <- readxl::read_xlsx("../data/aggregated_plotnames.xlsx", sheet = 4)
n5 <- readxl::read_xlsx("../data/aggregated_plotnames.xlsx", sheet = 5)
n6 <- readxl::read_xlsx("../data/aggregated_plotnames.xlsx", sheet = 6)
n7 <- readxl::read_xlsx("../data/aggregated_plotnames.xlsx", sheet = 7)
n8 <- readxl::read_xlsx("../data/aggregated_plotnames.xlsx", sheet = 8)

problem1 <- readxl::read_xlsx("../data/aggregated_problems.xlsx", sheet = 1)
problem2 <- readxl::read_xlsx("../data/aggregated_problems.xlsx", sheet = 2)
problem3 <- readxl::read_xlsx("../data/aggregated_problems.xlsx", sheet = 3)
problem4 <- readxl::read_xlsx("../data/aggregated_problems.xlsx", sheet = 4)
problem5 <- readxl::read_xlsx("../data/aggregated_problems.xlsx", sheet = 5)
problem6 <- readxl::read_xlsx("../data/aggregated_problems.xlsx", sheet = 6)
problem7 <- readxl::read_xlsx("../data/aggregated_problems.xlsx", sheet = 7)

exp_data <- data[c( 19, 20, 12, 21, 22)]
colnames(exp_data) <- c("n_papers", "years", "position","self_level", "code_contribution")
m = FAMD(exp_data[1:5], ncp=2, axes=c(1,2))

Code
factor_scores <- as.data.frame(m$ind$coord)

font_add_google("Lato")
showtext_opts(dpi = 100)
showtext_auto(enable = TRUE)

Table 1

Code
dm <- data.frame()

dim <- dplyr::tibble(
  Plots = c("../miniatures/1.png", "../miniatures/2.png", "../miniatures/3.png", "../miniatures/4.png", "../miniatures/5.png", "../miniatures/6.png", "../miniatures/7.png", "../miniatures/8.png"),
  Name = c("ERP plot", "Butterfly plot", "Topoplot", "Topoplot timeseries", "ERP grid", "ERP image", "Channel image", "Parallel plot"), 
  Time = c("x", "x", "", "(x)", "x", "x", "x", "(x)"),
  Channels = c("", "x", "x", "x", "x", "", "x", "x"), 
  Layout = c("", "", "x", "x", "x", "", "", ""), 
  Conditions = c("x", "", "", "", "(x)", "", "", "x"), 
  Trials = c("", "", "", "", "", "x", "", "(x)")
) 

t1 <- dim %>% 
  gt()  %>% 
  cols_align(align = "center", columns = c(Time, Channels, Layout, Conditions, Trials)) %>% 
  cols_width(
    Time ~ px(50),
    Channels ~ px(50),
    Layout ~ px(50),
    Conditions ~ px(50),
    Trials ~ px(50),
  ) %>% 
  text_transform(
    locations = cells_body(columns = Plots),
    fn = function(x) {
      lapply(x, function(x) {
              html(paste(local_image(filename = x)))
      })
    }
  ) %>%  opt_table_font(font = "Source Sans Pro")  %>% 
tab_options(#container.width = 550, container.height = 550, 
            data_row.padding = px(0.1), table.font.size = px(14), 
            container.padding.x = px(1),  column_labels.border.bottom.color = "black",column_labels.border.top.color = "white",
    column_labels.border.top.width = px(3),) %>% 
  tab_footnote(
  footnote = "x - full dimension, (x) - partial dimension",
  placement = "right"
)

t1
Plots Name Time Channels Layout Conditions Trials
ERP plot x x
Butterfly plot x x
Topoplot x x
Topoplot timeseries (x) x x
ERP grid x x x (x)
ERP image x x
Channel image x x
Parallel plot (x) x x (x)
x - full dimension, (x) - partial dimension
Code
t1_1 <- dim %>% flextable() %>%  valign(j = 2, valign = "center", part = "all") %>%
  compose(j = 'Plots', value = as_paragraph(as_image(Plots, width = 1, height = 0.6))) %>%
   padding(padding = 1, part = "all") %>%  autofit() %>% align(j = 3:7, align = "center") %>% 
   height_all(0.01, part = "all", unit = "cm") %>% 
  surround(
    j = 1:7,
    border.bottom = fp_border(color = "gray", style = "dashed"),
    part = "body"
  ) %>%   font(fontname = "Lato", part="all") %>% 
  hline_bottom(part = "body", border = fp_border(color = "black", width = 1)) |>
  add_footer_lines("x - full dimension, (x) - partial dimension")

t1_1

Plots

Name

Time

Channels

Layout

Conditions

Trials

ERP plot

x

x

Butterfly plot

x

x

Topoplot

x

x

Topoplot timeseries

(x)

x

x

ERP grid

x

x

x

(x)

ERP image

x

x

Channel image

x

x

Parallel plot

(x)

x

x

(x)

x - full dimension, (x) - partial dimension

Table 2

Code
plot_names <- c("ERP plot", "Butterfly plot", "Topoplot", "Topoplot\ntimeseries", "ERP grid", "ERP image", "Channel image", "Parallel plot")

t <- list(n1, n2, n3, n4, n5, n6, n7, n8) 

create_table <- function(t){
  tmp <- t[[1]] %>% mutate(total = sum(Scores)) %>% slice(1:3) %>% mutate(type = plot_names[1]) %>% rename_with(.cols = 1, ~"names") %>% relocate(type, names )
  
  for (i in 2:8){
    tmp <- t[[i]]  %>% mutate(total = sum(Scores)) %>% slice(1:3) %>% 
      mutate(type = plot_names[i]) %>% rename_with(.cols = 1, ~"names") %>% relocate(type, names) %>% 
      rbind(tmp, .)
  }
  tmp <- tmp %>% 
    group_by( type) %>%
    dplyr::mutate(groupRow = 1:n()) %>%
    ungroup() %>% mutate(p = round(as.numeric(Scores)/as.numeric(total), 2) * 100) %>% 
    mutate(score = paste(p, total, sep = "% out of ")) %>% 
    dplyr::mutate(type = ifelse(groupRow == 1, as.character(type), "")) %>%
    dplyr::mutate(Scores = ifelse(groupRow == 1, as.character(score), paste(p, "%", sep = ""))) %>%
    select(-c(groupRow, score))
}
plots2 <- c("../miniatures/1.png", "../miniatures/filler.png", "../miniatures/filler.png", "../miniatures/2.png", "../miniatures/filler.png", "../miniatures/filler.png", "../miniatures/3.png","../miniatures/filler.png", "../miniatures/filler.png", "../miniatures/4.png", "../miniatures/filler.png", "../miniatures/filler.png", "../miniatures/5.png", "../miniatures/filler.png", "../miniatures/filler.png", "../miniatures/6.png", "../miniatures/filler.png", "../miniatures/filler.png", "../miniatures/7.png", "../miniatures/filler.png", "../miniatures/filler.png", "../miniatures/8.png", "../miniatures/filler.png")

plotnames <- create_table(t) %>% data.frame() %>% 
  mutate(names = str_to_sentence(names)) %>% 
  mutate(names = str_replace(names, "Erp", "ERP")) %>% 
  mutate(names = str_replace(names, "erp", "ERP")) %>% tibble::add_column(Plots = plots2, .before = "type") %>% 
  dplyr::rename(`Plot types` = type,
         `Aggregated responses` = names) %>% select(-total, -p) 

t2 <- plotnames %>% flextable() %>% 
  merge_at(j= 1, i = 1:3) %>% merge_at(j= 1, i = 4:6) %>% 
  merge_at(j= 1, i = 7:9) %>% merge_at(j= 1, i = 10:12) %>%
  merge_at(j= 1, i = 13:15) %>% merge_at(j= 1, i = 16:18) %>%
  merge_at(j= 1, i = 19:21) %>% merge_at(j= 1, i = 22:23) %>%
  
  merge_at(j= 2, i = 1:3) %>% merge_at(j= 2, i = 4:6) %>% 
  merge_at(j= 2, i = 7:9) %>% merge_at(j= 2, i = 10:12) %>%
  merge_at(j= 2, i = 13:15) %>% merge_at(j= 2, i = 16:18) %>%
  merge_at(j= 2, i = 19:21) %>% merge_at(j= 2, i = 22:23)  %>% 
  valign(j = 2, valign = "center", part = "all") %>%
  compose(j = 'Plots', value = as_paragraph(as_image(Plots, width = 1, height = 0.6))) %>%
   padding(padding = 1, part = "all") %>% 
  autofit() %>% valign(valign = "top") %>% 
  height_all(0.01, part = "all", unit = "cm") %>% 
  surround(
    i = c(3, 6, 9, 12, 15, 18, 21),
    j = 1:4,
    border.bottom = fp_border(color = "gray", style = "dashed"),
    part = "body"
  ) %>%   font(fontname = "Lato", part="all") %>% 
  hline_bottom(part = "body", border = fp_border(color = "white", width = 3)) 
t2

Plots

Plot types

Aggregated responses

Scores

ERP plot

ERP (plot)

39% out of 197

Averaged ERP (plot)

19%

ERP wave(form)s

6%

Butterfly plot

Butterfly (plot)

48% out of 159

Single/individual channel ERP (plot)

17%

Multi(channel/electrode) ERP (plot)

14%

Topoplot

Topo(plot)

40% out of 192

Topography (plot)

39%

Topomap

7%

Topoplot
timeseries

Topo(plot) over time(series/course)

23% out of 189

Topography over time(series/course)

22%

Topo(plot)

12%

ERP grid

ERP over channels

15% out of 162

Multi(channel) plot

14%

Topographic ERP

14%

ERP image

ERP image

27% out of 114

Sorted ERP trials

19%

Trials

11%

Channel image

Channel(s) (ERP)

35% out of 96

Heatmap

16%

Channel image

9%

Parallel plot

(ERP) amplitudes

50% out of 8

Parallel coordinates

50%

Table 3

Code
prob_comb <- 
  rbind(problem1, problem2, problem3, problem4, problem5, problem6, problem7) %>%
  group_by(`Plot names`) %>%  mutate(index = match(`Plot names`, unique(`Plot names`)))  %>% filter(`Main problems` != "no complains") %>% 
  arrange(desc(Scores)) %>% slice(1:3) %>% 
  arrange(index) %>%  dplyr::select(`Plot names`, `Main problems`, Scores, Total) %>%  
  mutate(`Plot names` = str_to_sentence(`Plot names`)) %>% 
  mutate(`Plot names` = str_replace(`Plot names`, "Erp", "ERP")) %>% 
  mutate(`Plot names` = str_replace(`Plot names`, "erp", "ERP")) %>%  
  group_by(`Plot names`) %>%
  dplyr::mutate(groupRow = 1:n()) %>%
  ungroup() %>%
  mutate(p = round(as.numeric(Scores)/as.numeric(Total), 2) * 100) %>% 
  dplyr::group_by(`Plot names`) %>%   mutate(mx = max(p)) %>% 
  arrange(desc(mx), desc(p)) %>% 
  mutate(score = paste(p, Total, sep = "% out of ")) %>% 
  dplyr::mutate(`Plot names` = ifelse(groupRow == 1, as.character(`Plot names`), "")) %>%
  dplyr::mutate(Scores = ifelse(groupRow == 1, as.character(score), paste(p, "%", sep = ""))) %>%
  select(-c(groupRow, score, Total, p, mx)) 

plots3 <- c("../miniatures/1.png", "../miniatures/filler.png", "../miniatures/filler.png", "../miniatures/5.png", "../miniatures/filler.png", "../miniatures/filler.png", "../miniatures/4.png","../miniatures/filler.png", "../miniatures/filler.png", "../miniatures/7.png", "../miniatures/filler.png", "../miniatures/filler.png", "../miniatures/2.png", "../miniatures/filler.png", "../miniatures/filler.png", "../miniatures/3.png", "../miniatures/filler.png", "../miniatures/filler.png", "../miniatures/6.png", "../miniatures/filler.png", "../miniatures/filler.png")

probs <- prob_comb %>% tibble::add_column(Plots = plots3, .before = "Plot names")  %>% ungroup() 

t3 <- probs %>% flextable() %>% 
  merge_at(j= 1, i = 1:3) %>% merge_at(j= 1, i = 4:6) %>% 
  merge_at(j= 1, i = 7:9) %>% merge_at(j= 1, i = 10:12) %>%
  merge_at(j= 1, i = 13:15) %>% merge_at(j= 1, i = 16:18) %>% 
  merge_at(j= 1, i = 19:21) %>%
  merge_at(j= 2, i = 1:3) %>% merge_at(j= 2, i = 4:6) %>% 
  merge_at(j= 2, i = 7:9) %>% merge_at(j= 2, i = 10:12) %>%
  merge_at(j= 2, i = 13:15) %>% merge_at(j= 2, i = 16:18) %>%
  merge_at(j= 2, i = 19:21) %>% 
  padding(padding = 1, part = "all") %>% 
  valign(j = 2, valign = "center", part = "all") %>%
  compose(j = 'Plots', value = as_paragraph(as_image(Plots, width = 1, height = 0.6))) %>%
  autofit() %>%
  height_all(0.01, part = "all", unit = "cm") %>% 
  surround(
    i = c(3, 6, 9, 12, 15, 18, 21),
    j = 1:4,
    border.bottom = fp_border(color = "gray", style = "dashed"),
    part = "body"
  ) %>% 
  hline_bottom(part = "body", border = fp_border(color = "white", width = 3)) %>% 
  font(fontname = "Lato", part="all") 
t3 

Plots

Plot names

Main problems

Scores

ERP plot

uncertainty

34% out of 187

customization

6%

color

2%

ERP grid

legibility and scaling

25% out of 133

customization

6%

channel selection

2%

Topoplot timeseries

time specification

17% out of 153

color

5%

customization

4%

Channel image

sorting

14% out of 51

legibility and scaling

8%

color

4%

Butterfly plot

color

11% out of 125

channel selection

9%

adding topography

4%

Topoplot

channel selection

9% out of 175

head shape and montage

6%

color

5%

ERP image

sorting

7% out of 70

preprocessing

4%

smoothing

4%

Sup table 1

Code
log_fun <- function(df){
  mod <- glm(df$score ~ df$proxy, family = "binomial") 
  ci1 <- confint(mod)[2]
  ci2 <- confint(mod)[4]
  mod %>% tidy() %>% slice(-1) %>% cbind(ci1) %>% cbind(ci2)
}

vec <- names(data[25:51]) %>% str_split_i(., "\\? \\[", 2) %>%  str_sub(., 1, -2)

data[25:51] %>%
  rename_at(vars(colnames(.)), ~ vec) %>% 
  dplyr::select(-Other) %>% 
  mutate_at(vars(vec[1:26]), function(., na.rm = FALSE) (x = ifelse(.=="Yes", 1, 0))) %>%
  select_if(colSums(.) > 10) %>% 
  cbind(factor_scores[1], .) %>% dplyr::rename(proxy = !!names(.)[1]) %>% 
  gather(type, score, BESA:`Custom scripts`) %>% 
   dplyr::group_by(., type) %>% nest() %>% 
  dplyr::mutate(., model = map(data, log_fun)) %>% unnest() %>% 
  dplyr::select(type, estimate, std.error, p.value, ci1, ci2) %>%
  dplyr::group_by(type) %>%  slice(1) %>% mutate(p.value = round(as.numeric(p.value), 2), 
                                                 estimate = round(as.numeric(estimate), 2),
                                                 std.error = round(as.numeric(std.error), 2), 
                                                 CI = paste0('(' , round(ci1, 3), ', ', round(ci2, 3), ')' )) %>%
  dplyr::select(-ci1, -ci2) %>%
  mutate(p.value = cell_spec(p.value, bold = ifelse(p.value < 0.05, TRUE, FALSE))) %>% 
  dplyr::rename(`Analytical software` = type) %>% 
  kable(escape = F, booktabs = T) %>% 
  kable_minimal(full_width = F,  html_font = "Source Sans Pro")
Analytical software estimate std.error p.value CI
BESA -0.03 0.25 0.92 (-1.129, 0.234)
Brain Vision Analyser -0.08 0.20 0.67 (-0.766, 0.158)
Brainstorm -0.01 0.13 0.96 (-0.514, 0.207)
Custom scripts 0.84 0.37 0.02 (0.14, 1.587)
EEGLAB -0.03 0.10 0.75 (-0.274, 0.202)
ERPLAB 1.07 0.45 0.02 (0.21, 1.975)
FieldTrip 0.02 0.10 0.85 (-0.209, 0.265)
LIMO 0.05 0.13 0.72 (-0.472, 0.262)
MNE-Python -0.16 0.23 0.49 (-0.798, 0.099)
SPM -0.05 0.26 0.84 (-1.072, 0.213)
Unfold -0.56 0.73 0.45 (-2.045, 0.203)

Sup table 2

Code
cor_fun <- function(df){
  p.value <- cor.test(df$proxy, df$score, method = "spearman")$p.value
  mod <- spearman.ci(df$proxy, df$score) %>% tidy() %>% cbind(p.value) 
  }
feature <- data[52:60] %>% rename_all(., ~str_split_i(colnames(data[52:60]), "\\? \\[", 2) %>% str_sub(., 1, -2) ) %>%  
  mutate_at(c(colnames(.)), 
        funs(recode(.,
        "Very important"= 2, "Important"= 1, "Neutral"= 0,
        "Low importance"= -1, "Not at all important" = -2 )))  %>% 
  cbind(., factor_scores[1]) %>%  
  rename_at(vars(colnames(.)), ~ c("subplot", "attributes", "speed", "publicable", "reproducable", "zooming", "interactive", "gui", "coding", "proxy")) 

feature %>% 
  gather(type, score, subplot:coding) %>% 
  dplyr::group_by(., type) %>% nest() %>% 
  dplyr::mutate(., model = map(data, cor_fun)) %>% unnest() %>% 
  dplyr::select(type, estimate, conf.low.Inf, conf.high.Sup, p.value) %>% # , method
  dplyr::group_by(type) %>%  slice(1) %>% mutate(estimate = round(as.numeric(estimate), 2),
                                                 CI = paste0('(' , round(conf.low.Inf, 3), ', ', round(conf.high.Sup, 3), ')' ),
                                                             p.value = round(as.numeric(p.value), 2)) %>% 
  mutate(p.value = cell_spec(p.value, bold = ifelse(p.value < 0.05, TRUE, FALSE))) %>% 
  dplyr::rename(`Software feature` = type, `Spearman rho` = estimate) %>% 
  select(-conf.low.Inf, -conf.high.Sup) %>% 
  kable(escape = F, booktabs = T) %>% 
  kable_minimal(full_width = F,  html_font = "Source Sans Pro") 
Software feature Spearman rho p.value CI
attributes -0.03 0.71 (-0.164, 0.12)
coding 0.12 0.09 (-0.014, 0.252)
gui -0.17 0.01 (-0.301, -0.036)
interactive -0.11 0.11 (-0.241, 0.02)
publicable -0.15 0.03 (-0.287, 0.005)
reproducable 0.02 0.81 (-0.126, 0.159)
speed -0.01 0.83 (-0.145, 0.125)
subplot 0.11 0.11 (-0.015, 0.247)
zooming -0.06 0.39 (-0.193, 0.062)