library(psych) library(tidyverse) # Načtení dat df <- read_csv2("https://is.muni.cz/el/fss/podzim2024/PSYb2320/um/datasets/personality_all.csv") # Načtení dat i se správnou definíc missing values df <- read_csv2("data/personality_all.csv", na = c("", "-99")) # Funkce distinct pro sloupec gender df %>% distinct(gender) # Převod gender na factor df <- df %>% mutate(gender = factor(gender, levels = c("F", "M"), labels = c("Boy", "Girl"))) # Kombinace grade a class df <- df %>% mutate(grade_class = str_c(grade, class), .after = class) # Výběr položek začínajících na "nfc" df %>% select(starts_with("nfc")) # Ověření reliability škál NFC df %>% select(starts_with("nfc")) %>% psych::alpha() # Použití funkce summary() na dataset df %>% summary() # Rekódování hodnot položku po položce df %>% mutate(nfc_10 = 6 - nfc_10, nfc_11 = 6 - nfc_11) # Položky NFC 10 až 16 jsou reverzní # Podíváme se na ně nejprve pomocí funkce select() df %>% select(nfc_10:nfc_16) # Pomocí funkce across() v rámci mutate() df %>% mutate( across(nfc_10:nfc_16, ~6 - .x) ) %>% select(nfc_10:nfc_16) # Vektor nfc_reversed s reverzními položkami NFC (10 až 16) nfc_reversed <- str_c("nfc_", 10:16) # Použití funkce all_of() df %>% mutate(across( all_of(nfc_reversed), ~6 - .x) ) %>% select(all_of(nfc_reversed)) # A co reverzní položky IPIP? # Jedná se o typo položky nums <- c(2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 29, 30, 32, 34, 36, 38, 39, 44, 46, 49) nums # Vytvoření vektoru s ipip_reversed s reverzními položkami IPIP # Využití funkce str_c() # a také funkce str_pad() ipip_reversed <- str_c("ipip_", nums) ipip_reversed nums <- str_pad(nums, pad = 0, width = 2) nums ipip_reversed <- str_c("ipip_", nums) # Kombinace všech reverzních položek do jednoho vektoru reversed_items reversed_items <- c(nfc_reversed, ipip_reversed) reversed_items # Uložení nerekódovaného datasetu do nového objektu not_recoded not_recoded <- df # Finální rekódování všech položek df <- df %>% mutate( across(all_of(reversed_items), ~6 - .x) ) # Cronbachovo alfa pro škálu NFC df %>% select(nfc_01:nfc_16) %>% psych::alpha() str_c("nfc_", str_pad(seq(1, 16), pad = 0, width = 2)) # Co kdybychom si vytvořili vlastní funkci item_range pro vytváření # jmen položek item_range <- function(prefix, suffix) { str_c(prefix, str_pad(suffix, pad = 0, width = 2)) } # Příklad použití této funkce item_range("nfc_", 1:16) # Co kdybychom si vytvořili list "items" s názvy položek jednotlivých škál # NFC: 1 až 16 # Extraversion: 1 6 11 16 21 26 31 36 41 46 # Agreeableness: 2 7 12 17 22 27 32 37 42 47 # Conscientiousness: 3 8 13 18 23 28 33 38 43 48 # Emotional stability: 4 9 14 19 24 29 34 39 44 49 # Intellect: 5 10 15 20 25 30 35 40 45 50 items <- list( nfc = item_range("nfc_", 1:16), ext = item_range("ipip_", seq(1, 50, by = 5)), con = item_range("ipip_", seq(2, 50, by = 5)) ) items # Odkázat se na jednotlivé prvky listu items jde pomocí $ items$nfc items$ext # Funkce row_mean() pro výpočet celkových skórů jako průměr položek row_mean <- function(..., max.na = 0) { data <- pick(...) n_miss <- data %>% is.na() %>% rowSums() output <- data %>% rowMeans(na.rm = TRUE) output[n_miss > max.na] <- NA_real_ return(output) } df # Upltnění funkce row_mean() pro výpočet celkových skórů # nfc, ext, con # Jejich umístění někde na začátek df <- df %>% mutate(nfc = row_mean(all_of(items$nfc)), ext = row_mean(all_of(items$ext)), con = row_mean(all_of(items$con)), .after = grade_class) # Výpočet deskriptivních statistik v závislosti na ročníku a pohlaví # M, SD, skew df %>% group_by(gender, grade) %>% summarise( M = mean(nfc, na.rm = TRUE), SD = sd(nfc, na.rm = TRUE), skew = psych::skew(nfc) ) # A co kvantily s pomocí funkce quantile() # Se summarise() by to šlo, ale máme varování df %>% group_by(gender, grade) %>% summarise( q = quantile(nfc, probs = c(0, .25, .5, .75, 1), na.rm = TRUE) ) # Lepší je tedy použít reframe() df %>% group_by(gender, grade) %>% reframe( probs = c(0, .25, .5, .75, 1), q = quantile(nfc, probs = c(0, .25, .5, .75, 1), na.rm = TRUE) ) # Pokud se nám výstup nelíbí, můžeme použít navíc pivot_wider() df %>% group_by(gender, grade) %>% reframe( probs = c(0, .25, .5, .75, 1), q = quantile(nfc, probs = c(0, .25, .5, .75, 1), na.rm = TRUE) ) %>% pivot_wider(names_from = probs, values_from = q, names_prefix = "q") # Co když chceme vypočíst statistiky pro více než jednu proměnnou? df %>% select(gender, grade, nfc, ext, con) # Vybereme s datasetu id, gender, grade, nfc, ext a con # a zkusíme to nejdříve s využitím pivot_longer() df %>% select(id, gender, grade, nfc, ext, con) %>% pivot_longer(nfc:con, values_to = "value", names_to = "variable") # Výsledek si uložíme do nové matice df_longer() df_longer <- df %>% select(id, gender, grade, nfc, ext, con) %>% pivot_longer(nfc:con, values_to = "value", names_to = "variable") # Pak můžeme opět použít group_by() a summarise() # Vypočteme si M, SD, ale i počet chybějících a validních hodnot df_longer %>% group_by(gender, grade, variable) %>% summarise( M = mean(value, na.rm = TRUE), SD = sd(value, na.rm = TRUE), miss = sum(is.na(value)), n = sum(!is.na(value)), ) # Pokud chceme, můžeme také nejprve vyřadit řádky s chybějícími hodnotami # pomocí funkce drop_na() df_longer %>% group_by(gender, grade, variable) %>% drop_na(value) %>% summarise( M = mean(value), SD = sd(value), n = n() ) # Šlo by to i pomocí funkce across # Nejprve si vypočteme jenom průměry df %>% group_by(gender, grade) %>% summarise( across(c(nfc, ext, con), mean) ) # Do listu přidáme více funkcí včetně sd() df %>% group_by(gender, grade) %>% summarise( across(c(nfc, ext, con), list(M = mean, SD = sd)) ) # Musíme použít tzv. lambda funkce, abychom mohli měnit další argumenty, # jako např. na.rm df %>% group_by(gender, grade) %>% summarise( across(c(nfc, ext, con), list(M = ~mean(.x, na.rm = TRUE), SD = ~sd(.x, na.rm = TRUE))) ) # Ještě si můžeme vytvoři graf s četnostmi pro ročník a pohlaví # Můžeme nejprve vypočíst četnosti pomocí count() df %>% count(grade, gender) # Pak přidáme relativní četnosti df %>% count(grade, gender) %>% mutate(p = n/sum(n)) # Výsledek pošleme do ggplotu a použijeme funkci geom_col() df %>% count(grade, gender) %>% mutate(p = n/sum(n)) %>% ggplot(aes(x = grade, y = p, fill = gender)) + geom_col() # Ještě změníme pozici na position = "dodge" df %>% count(grade, gender) %>% mutate(p = n/sum(n)) %>% ggplot(aes(x = grade, y = p, fill = gender)) + geom_col(position = "dodge") # A změníme barvy # třeba #0D92F4 pro kluky a #C62E2E df %>% count(grade, gender) %>% mutate(p = n/sum(n)) %>% ggplot(aes(x = grade, y = p, fill = gender)) + geom_col(position = "dodge") + scale_fill_manual(values = c("#0D92F4", "#C62E2E"))