#title:"Smieszna nazwa projektu"
#author: "Beniamin Gralak i Jakub Gużewski"
#date: "2025-01-19"
#output: html_document
Celem naszego projektu jest przeprowadzenie szczegółowej analizy wpływu różnych czynników na wyniki egzaminacyjne uczniów. Badanie opiera się na danych obejmujących szereg zmiennych, które mogą mieć istotne znaczenie dla osiąganych rezultatów. W szczególności skupiamy się na analizie zależności między wynikami egzaminów a takimi czynnikami jak liczba godzin snu, czas poświęcony na naukę, płeć ucznia oraz odległość z domu do szkoły itp.
Wczytujemy dane z zewnętrznego źródła oraz potrzebne biblioteki do analizy i wizualizacji danych.
options(repos = c(CRAN = "https://cloud.r-project.org/"))
library(RCurl)
x <- getURL('https://raw.githubusercontent.com/Guzioz/Smieszna-nazwa-projektu-Analiza/refs/heads/main/czynniki.csv')
czynniki <- read.csv(text = x)
library(naniar)
library(mice)
install.packages("gridExtra")
library(gridExtra)
library(ggplot2)
install.packages("corrplot")
library(corrplot)
library(moments)
install.packages("ggstatsplot")
library("ggstatsplot")
install.packages("knitr")
install.packages("kableExtra")
library(knitr)
library(kableExtra)
- Exam_Score: wynik egzaminu końcowego
- Hours_Studied: liczba godzin nauki w tygodniu
- Sleep_Hours: średnia liczba godzin snu w ciągu nocy
- Parental_Involvement: Poziom zaangażowania rodziców w edukację ucznia (Low/Medium/High)
- Access_to_Resources: Dostępność zasobów edukacyjnych (Low/Medium/High)
- Peer_Influence: Wpływ rówieśników na wyniki w nauce (Positive/Negative/Neutral)
- Motivation_Level: Poziom motywacji ucznia (Low/Medium/High)
- School_Type: Rodzaj szkoły, do której uczęszcza uczeń (Public/Private)
- Learning_Disabilities: Obecność trudności w uczeniu się (Yes/No)
- Family_Income: Poziom dochodów rodziny (Low/Medium/High)
Analizujemy strukturę danych oraz sprawdzamy podstawowe statystyki opisowe każdej zmiennej, aby zrozumieć, jakie dane posiadamy i jakie są potencjalne problemy, jak na przykład brakujące zmienne.
summary(czynniki)
## Hours_Studied Attendance Parental_Involvement Access_to_Resources
## Min. : 1.00 Min. : 60.00 Length:6607 Length:6607
## 1st Qu.:16.00 1st Qu.: 70.00 Class :character Class :character
## Median :20.00 Median : 80.00 Mode :character Mode :character
## Mean :19.98 Mean : 79.98
## 3rd Qu.:24.00 3rd Qu.: 90.00
## Max. :44.00 Max. :100.00
##
## Extracurricular_Activities Sleep_Hours Previous_Scores
## Length:6607 Min. : 4.000 Min. : 50.00
## Class :character 1st Qu.: 6.000 1st Qu.: 63.00
## Mode :character Median : 7.000 Median : 75.00
## Mean : 7.026 Mean : 75.07
## 3rd Qu.: 8.000 3rd Qu.: 88.00
## Max. :10.000 Max. :100.00
## NA's :350
## Motivation_Level Internet_Access Tutoring_Sessions Family_Income
## Length:6607 Length:6607 Min. :0.000 Length:6607
## Class :character Class :character 1st Qu.:1.000 Class :character
## Mode :character Mode :character Median :1.000 Mode :character
## Mean :1.494
## 3rd Qu.:2.000
## Max. :8.000
##
## Teacher_Quality School_Type Peer_Influence Physical_Activity
## Length:6607 Length:6607 Length:6607 Min. :0.000
## Class :character Class :character Class :character 1st Qu.:2.000
## Mode :character Mode :character Mode :character Median :3.000
## Mean :2.968
## 3rd Qu.:4.000
## Max. :6.000
##
## Learning_Disabilities Parental_Education_Level Distance_from_Home
## Length:6607 Length:6607 Length:6607
## Class :character Class :character Class :character
## Mode :character Mode :character Mode :character
##
##
##
##
## Gender Exam_Score
## Length:6607 Min. : 56.00
## Class :character 1st Qu.: 65.00
## Mode :character Median : 67.00
## Mean : 67.22
## 3rd Qu.: 69.00
## Max. :101.00
## NA's :300
str(czynniki)
## 'data.frame': 6607 obs. of 20 variables:
## $ Hours_Studied : int 23 19 24 29 19 19 29 25 17 23 ...
## $ Attendance : int 84 64 98 89 92 88 84 78 94 98 ...
## $ Parental_Involvement : chr "Low" "Low" "Medium" "Low" ...
## $ Access_to_Resources : chr "High" "Medium" "Medium" "Medium" ...
## $ Extracurricular_Activities: chr "No" "No" "Yes" "Yes" ...
## $ Sleep_Hours : int 7 8 7 8 6 8 NA 6 6 8 ...
## $ Previous_Scores : int 73 59 91 98 65 89 68 50 80 71 ...
## $ Motivation_Level : chr "Low" "Low" "Medium" "Medium" ...
## $ Internet_Access : chr "Yes" "Yes" "Yes" "Yes" ...
## $ Tutoring_Sessions : int 0 2 2 1 3 3 1 1 0 0 ...
## $ Family_Income : chr "Low" "Medium" "Medium" "Medium" ...
## $ Teacher_Quality : chr "Medium" "Medium" "Medium" "Medium" ...
## $ School_Type : chr "Public" "Public" "Public" "Public" ...
## $ Peer_Influence : chr "Positive" "Negative" "Neutral" "Negative" ...
## $ Physical_Activity : int 3 4 4 4 4 3 2 2 1 5 ...
## $ Learning_Disabilities : chr "No" "No" "No" "No" ...
## $ Parental_Education_Level : chr "High School" "College" "Postgraduate" "High School" ...
## $ Distance_from_Home : chr "Near" "Moderate" "Near" "Moderate" ...
## $ Gender : chr "Male" "Female" "Male" "Male" ...
## $ Exam_Score : int 67 61 74 71 NA 71 67 66 69 72 ...
Poniżej przedstawiliśmy brakujące wartości jakie pojawiły się w bazie danych.
LICZBA_NA <- data.frame(liczba_brakow = colSums(is.na(czynniki)))
LICZBA_NA
## liczba_brakow
## Hours_Studied 0
## Attendance 0
## Parental_Involvement 0
## Access_to_Resources 0
## Extracurricular_Activities 0
## Sleep_Hours 350
## Previous_Scores 0
## Motivation_Level 0
## Internet_Access 0
## Tutoring_Sessions 0
## Family_Income 350
## Teacher_Quality 78
## School_Type 0
## Peer_Influence 0
## Physical_Activity 0
## Learning_Disabilities 0
## Parental_Education_Level 90
## Distance_from_Home 67
## Gender 0
## Exam_Score 300
Poniżej przedstawiliśmy ilości unikatowych wartości dla każdej zmiennej.
WARTOSCI_BEZ_NA <- data.frame(liczba_unikatowych_wartosci = sapply(czynniki, function(x) length(unique(na.omit(x)))))
WARTOSCI_BEZ_NA
## liczba_unikatowych_wartosci
## Hours_Studied 41
## Attendance 41
## Parental_Involvement 3
## Access_to_Resources 3
## Extracurricular_Activities 2
## Sleep_Hours 7
## Previous_Scores 51
## Motivation_Level 3
## Internet_Access 2
## Tutoring_Sessions 9
## Family_Income 3
## Teacher_Quality 3
## School_Type 2
## Peer_Influence 3
## Physical_Activity 7
## Learning_Disabilities 2
## Parental_Education_Level 3
## Distance_from_Home 3
## Gender 2
## Exam_Score 44
Wyświetlamy posiadane wartości oraz standaryzujemy. Robimy ograniczenia, chociażby dla wyników, które nie powinny przekraczać 100. Dodatkowo przypisujemy zmienne kategoryczne do faktorów, w celu przeprowadzenia dalszej analizy.
typ_danych <- data.frame(typ = sapply(czynniki, class))
typ_danych
## typ
## Hours_Studied integer
## Attendance integer
## Parental_Involvement character
## Access_to_Resources character
## Extracurricular_Activities character
## Sleep_Hours integer
## Previous_Scores integer
## Motivation_Level character
## Internet_Access character
## Tutoring_Sessions integer
## Family_Income character
## Teacher_Quality character
## School_Type character
## Peer_Influence character
## Physical_Activity integer
## Learning_Disabilities character
## Parental_Education_Level character
## Distance_from_Home character
## Gender character
## Exam_Score integer
Na podstawie poniżej tabeli możemy zobaczyć, jak wyglądają unikalne wartości dla każdej kolumny. Jest to etap, który pozwala nam zwizualizować badaną baze danych.
columns_to_check <- c("Hours_Studied", "Attendance", "Parental_Involvement", "Access_to_Resources",
"Extracurricular_Activities", "Sleep_Hours", "Previous_Scores",
"Motivation_Level", "Internet_Access", "Tutoring_Sessions", "Family_Income",
"Teacher_Quality", "School_Type", "Peer_Influence", "Physical_Activity",
"Learning_Disabilities", "Parental_Education_Level", "Distance_from_Home",
"Gender", "Exam_Score")
unique_values_all <- lapply(czynniki[columns_to_check], unique)
print(unique_values_all)
## $Hours_Studied
## [1] 23 19 24 29 25 17 21 9 10 14 22 15 12 20 11 13 16 18 31 8 26 28 4 35 27
## [26] 33 36 43 34 1 30 7 32 6 38 5 3 2 39 37 44
##
## $Attendance
## [1] 84 64 98 89 92 88 78 94 80 97 83 82 68 60 70 75 99 74 65
## [20] 62 91 90 66 69 72 63 61 86 77 71 67 87 73 96 100 81 95 79
## [39] 85 76 93
##
## $Parental_Involvement
## [1] "Low" "Medium" "High"
##
## $Access_to_Resources
## [1] "High" "Medium" "Low"
##
## $Extracurricular_Activities
## [1] "No" "Yes"
##
## $Sleep_Hours
## [1] 7 8 6 NA 10 9 5 4
##
## $Previous_Scores
## [1] 73 59 91 98 65 89 68 50 80 71 88 87 97 72 74 70 82 58 99
## [20] 84 100 75 54 90 94 51 57 66 96 93 56 52 63 79 81 69 95 60
## [39] 92 77 62 85 78 64 76 55 86 61 53 83 67
##
## $Motivation_Level
## [1] "Low" "Medium" "High"
##
## $Internet_Access
## [1] "Yes" "No"
##
## $Tutoring_Sessions
## [1] 0 2 1 3 4 5 6 7 8
##
## $Family_Income
## [1] "Low" "Medium" "High" NA
##
## $Teacher_Quality
## [1] "Medium" "High" "Low" NA
##
## $School_Type
## [1] "Public" "Private"
##
## $Peer_Influence
## [1] "Positive" "Negative" "Neutral"
##
## $Physical_Activity
## [1] 3 4 2 1 5 0 6
##
## $Learning_Disabilities
## [1] "No" "Yes"
##
## $Parental_Education_Level
## [1] "High School" "College" "Postgraduate" NA
##
## $Distance_from_Home
## [1] "Near" "Moderate" "Far" NA
##
## $Gender
## [1] "Male" "Female"
##
## $Exam_Score
## [1] 67 61 74 71 NA 66 69 72 68 70 65 64 60 63 62 100 76 79 73
## [20] 78 89 75 59 86 97 83 84 80 58 94 92 82 77 101 88 91 99 87
## [39] 57 96 98 95 85 93 56
czynniki <- subset(czynniki, Exam_Score <= 100)
czynniki$Family_Income <- factor(czynniki$Family_Income, levels = c("Low", "Medium", "High"))
czynniki$Teacher_Quality <- factor(czynniki$Teacher_Quality, levels = c("Low", "Medium", "High"))
czynniki$Parental_Education_Level <- factor(czynniki$Parental_Education_Level, levels = c("High School", "College", "Postgraduate"))
czynniki$Distance_from_Home <- factor(czynniki$Distance_from_Home, levels = c("Near", "Moderate", "Far"))
czynniki$Motivation_Level <- factor(czynniki$Motivation_Level, levels = c("Low", "Medium", "High"))
czynniki$Internet_Access <- factor(czynniki$Internet_Access, levels = c("Yes", "No"))
czynniki$Learning_Disabilities <- factor(czynniki$Learning_Disabilities, levels = c("No", "Yes"))
czynniki$School_Type <- factor(czynniki$School_Type, levels = c("Public", "Private"))
czynniki$Extracurricular_Activities <- factor(czynniki$Extracurricular_Activities, levels = c("No", "Yes"))
czynniki$Peer_Influence <- factor(czynniki$Peer_Influence, levels = c("Positive", "Negative", "Neutral"))
czynniki$Gender <- factor(czynniki$Gender, levels = c("Male", "Female"))
Początkowo usuwamy brakujące wartości wyników egzaminu, ze względu na to, że jest to zmienna badana. W celu ograniczenia ryzyka, uważamy, że jest to ważne dla dalszej analizy.
czynniki2 <- subset(czynniki, !is.na(Exam_Score))
LICZBA_NA2 <- data.frame(liczba_brakow = colSums(is.na(czynniki2)))
LICZBA_NA2
## liczba_brakow
## Hours_Studied 0
## Attendance 0
## Parental_Involvement 0
## Access_to_Resources 0
## Extracurricular_Activities 0
## Sleep_Hours 339
## Previous_Scores 0
## Motivation_Level 0
## Internet_Access 0
## Tutoring_Sessions 0
## Family_Income 325
## Teacher_Quality 71
## School_Type 0
## Peer_Influence 0
## Physical_Activity 0
## Learning_Disabilities 0
## Parental_Education_Level 88
## Distance_from_Home 63
## Gender 0
## Exam_Score 0
Reszte zmiennych postanawiamy zastąpić przy użyciu metody mice. Która będzie najlepsza wobec zastąpywania brakujących wartości dla naszych danych. Ze względu na to, że mice jest techniką wielokrotnej imputacji, która polega na generowaniu kilku zestawów imputowanych danych, a nie tylko jednej “najlepszej” wartości.
method <- make.method(czynniki2)
method[c("Sleep_Hours", "Previous_Scores", "Tutoring_Sessions", "Physical_Activity", "Exam_Score")] <- "pmm"
method[c("Internet_Access", "Gender", "Extracurricular_Activities")] <- "logreg"
method[c("Family_Income", "Teacher_Quality", "Parental_Education_Level", "Distance_from_Home",
"Motivation_Level", "Learning_Disabilities", "School_Type", "Peer_Influence")] <- "polyreg"
czynnikisleep <- mice(czynniki2, m = 5, method = method, seed = 500)
czynniki3 <- complete(czynnikisleep, 1)
LICZBA_NA <- data.frame(liczba_brakow = colSums(is.na(czynniki3)))
LICZBA_NA
## liczba_brakow
## Hours_Studied 0
## Attendance 0
## Parental_Involvement 0
## Access_to_Resources 0
## Extracurricular_Activities 0
## Sleep_Hours 0
## Previous_Scores 0
## Motivation_Level 0
## Internet_Access 0
## Tutoring_Sessions 0
## Family_Income 0
## Teacher_Quality 0
## School_Type 0
## Peer_Influence 0
## Physical_Activity 0
## Learning_Disabilities 0
## Parental_Education_Level 0
## Distance_from_Home 0
## Gender 0
## Exam_Score 0
Tworzymy wykres pudełkowy, oraz histogram dla zmiennej wynikowej(Exam_Score).
b1 <- ggplot(czynniki3, aes(y = Exam_Score)) +
geom_boxplot() +
labs(title = "Exam_Score")
h1 <- ggplot(czynniki3) +
aes(x = Exam_Score) +
geom_histogram(bins = 30, fill = "#0c4c8a") +
theme_minimal()
grid.arrange(b1, h1, nrow = 1)
Na powyższych wykresach możemy zauważyć, że znacząca większość uczniów osiąga wyniki między 65-70%. Z drugiej strony widzimy odstające wartości powyżej 70%, co może sugerować skośność prawostronną, co zostanie przeanalizowane w dalszej części projektu.
Tworzymy wykresy kołowe dla zmiennych kategorycznych, takich jak dostęp do Internetu, oraz obecności trudności w nauce, aby zobaczyć proporcje poszczególnych kategorii i łatwiej zinterpretować dane.
fill_colors <- c("Yes" = "blue", "No" = "red")
create_pie_chart <- function(data, var, fill_colors) {
ggplot(data, aes(x = "", fill = as.factor(!!sym(var)))) +
geom_bar(width = 1, color = "white") +
coord_polar(theta = "y") +
scale_fill_manual(values = fill_colors) +
labs(title = paste("Pie Chart of", var), fill = "Categories") +
theme_void() +
theme(legend.position = "top") +
geom_text(aes(label = scales::percent(..count.. / sum(..count..))),
stat = "count", position = position_stack(vjust = 0.5), color = "white")
}
pie_internet <- create_pie_chart(czynniki3, "Internet_Access", fill_colors)
pie_learning_disabilities <- create_pie_chart(czynniki3, "Learning_Disabilities", fill_colors)
pie_internet | pie_learning_disabilities
Powyższy wykres przedstawiający procentowy dostęp uczniów do internetu, ukazuje, że tylko 8% uczniów nie ma dostępu do internetu.
Kolejny wykres kołowy, ukazuje, że aż 11% uczniów ma pewne trudności w nauce, co może sugerować obecność pewnych dysfunkcji wśród uczniów
Tworzymy wykresy słupkowe dla zmiennych kategorycznych, takich jak płeć, wpływ rówieśników, poziomu dochodu rodziny, oraz odległości od domu do szkoły, aby porównać liczebność grup i zauważyć ewentualne nierówności.
gender_colors <- c("Female" = "pink", "Male" = "blue")
peer_influence_colors <- c("Neutral" = "blue", "Positive" = "green", "Negative" = "red")
family_income_colors <- c("Low" = "red", "Medium" = "blue", "High" = "green")
distance_from_home_colors <- c("Near" = "green", "Moderate" = "blue", "Far" = "red")
gender_plot <- ggplot(czynniki3, aes(x = Gender, fill = as.factor(Gender))) +
geom_bar() +
scale_fill_manual(values = gender_colors) +
labs(title = "Bar Plot of Gender", x = "Gender", y = "Count") +
theme_minimal()
family_income_plot <- ggplot(czynniki3, aes(x = Family_Income, fill = as.factor(Family_Income))) +
geom_bar() +
scale_fill_manual(values = family_income_colors) +
labs(title = "Bar Plot of Family Income", x = "Family Income", y = "Count") +
theme_minimal()
distance_plot <- ggplot(czynniki3, aes(x = Distance_from_Home, fill = as.factor(Distance_from_Home))) +
geom_bar() +
scale_fill_manual(values = distance_from_home_colors) +
labs(title = "Bar Plot of Distance from Home", x = "Distance from Home", y = "Count") +
theme_minimal()
peer_influence_plot <- ggplot(czynniki3, aes(x = Peer_Influence, fill = as.factor(Peer_Influence))) +
geom_bar() +
scale_fill_manual(values = peer_influence_colors) +
labs(title = "Bar Plot of Peer Influence", x = "Peer Influence", y = "Count") +
theme_minimal()
(gender_plot / family_income_plot)
Na podstawie powyższych wykresów możemy zauważyć, że większość wśród uczniów stanowią mężczyźni o prawie tysiąc uczniów więcej.
Dodatkowo, znacząca większość uczniów pochodzi z rodzin, które posiadają dochody niskie, oraz średnio(około tylu samo uczniów na katergorie), a niewiele ponad tysiąc uczniów pochodzi z rodzin oiągających wysokie dochody.
(distance_plot / peer_influence_plot)
Kolejny wykres ukazuje, że znacząco ponad połowa uczniów pochodzi z rejonów, które znajdują się blisko szkoły.
Ostatni wykres ukazuje wpływ rówieśników na ucznia, ciekawym faktem może być to, że porównywalnie tyle samo uczniów odczówa pozytywny wpływ, jak i negatywny.
Tworzymy wykresy pudełkowe, by zobaczyć, jak jakość nauczycieli, poziom wyedukowania rodziców, poziom motywacji, czy typ szkoły wpływają na wyniki egzaminów.
plot1 <- ggplot(czynniki3, aes_string(x = "Teacher_Quality", y = "Exam_Score", fill = "Teacher_Quality")) +
geom_boxplot(color = "black") +
labs(title = "Boxplot of Exam_Score by Teacher_Quality", x = "Teacher Quality", y = "Exam Score") +
scale_fill_manual(values = rainbow(length(unique(czynniki3[["Teacher_Quality"]])))) +
theme_minimal()
print(plot1)
Na podstawie wykresu jakości nauczycieli, a wyniku egzaminu, możemy zauważyć lekką asymetryczność, dla wyników low, oraz high. Uczniowie, mający nauczycieli, których ocenili na wysoką jakość, mieli szanse na osiągnięcie lepszych wyników, niż Ci z na przykład niską jakościa. Możemy dodatkowo zauważyć, że nauczyciele ocenieni na jakość średnią, mieli najwięcej odstający wyników.
plot2 <- ggplot(czynniki3, aes_string(x = "Parental_Education_Level", y = "Exam_Score", fill = "Parental_Education_Level")) +
geom_boxplot(color = "black") +
labs(title = "Boxplot of Exam_Score by Parental_Education_Level", x = "Parental Education Level", y = "Exam Score") +
scale_fill_manual(values = rainbow(length(unique(czynniki3[["Parental_Education_Level"]])))) +
theme_minimal()
print(plot2)
Na podstawie wykresu poziom wykształcenia rodziców, a wyniku egzaminu, możemy zauważyć, że im wyższe wykształcenie rodziców, tym wyniki osiągane przez uczniów były większe. Z drugiej strony możemy zauważyć asymetryczność dla rodziców z wykształceniem wyższym. Najwięcej odstających wartośći jest dla wyników uczniów, których rodzice mają wykształcene policealne.
plot3 <- ggplot(czynniki3, aes_string(x = "Motivation_Level", y = "Exam_Score", fill = "Motivation_Level")) +
geom_boxplot(color = "black") +
labs(title = "Boxplot of Exam_Score by Motivation_Level", x = "Motivation Level", y = "Exam Score") +
scale_fill_manual(values = rainbow(length(unique(czynniki3[["Motivation_Level"]])))) +
theme_minimal()
print(plot3)
Na podstawie wykresu poziom motywacji, a wyniku egzaminu, możemy zauważyć, że im wyższa motywacja, tym wyniki osiągane przez uczniów były większe. Z drugiej strony możemy zauważyć asymetryczność dla motywacji niskiej i wysokiej. Najwięcej odstających wartośći jest dla wyników uczniów, z motywacją średnią.
plot4 <- ggplot(czynniki3, aes_string(x = "School_Type", y = "Exam_Score", fill = "School_Type")) +
geom_boxplot(color = "black") +
labs(title = "Boxplot of Exam_Score by School_Type", x = "School Type", y = "Exam Score") +
scale_fill_manual(values = rainbow(length(unique(czynniki3[["School_Type"]])))) +
theme_minimal()
print(plot4)
Na podstawie wykresu typ szkoły, a wyniku egzaminu, możemy zauważyć, że wyniki dla obu szkół rozkładają się podobnie symetrycznie. Z druegiej strony możemy zauważyć, więcej wyników odstającyh dla uczniów ze szkół publicznych.
Tworzymy histogramy dla zmiennych liczbowych jak, godziny nauki, liczba godzin snu, liczba sesji korepetycji w miesiącu, średnia liczba godzin aktywności fizycznej, aby zrozumieć rozkład każdej zmiennej i zauważyć ewentualne skupienia lub wartości odstające.
plots <- list()
numeric_vars <- c("Hours_Studied", "Sleep_Hours", "Tutoring_Sessions", "Physical_Activity")
for (var in numeric_vars) {
hist_plot <- ggplot(czynniki3, aes_string(x = var)) +
geom_histogram(bins = 30, fill = "#0c4c8a", color = "black") +
labs(title = paste("Histogram of", var), x = var, y = "Frequency") +
theme_minimal()
plots[[var]] <- hist_plot
}
(plots[["Hours_Studied"]] | plots[["Sleep_Hours"]]) /
(plots[["Tutoring_Sessions"]] | plots[["Physical_Activity"]])
Możemy zauważyć wobec rozkładów liczby godzin nauki, snu, oraz aktywności fizycznej mniej więcej symetryczne rozkłady, które nie mają większych odstających wartości. Z drugiej strony, na wykresie średniej liczby sesji korepetycji w miesiącu, możemy zaobserwować skośność prawostronną, gdzie większość uczniów ma maksymalnie do około 2 sesji miesięcznie, a reszta potrafi mieć nawet do 8 sesji miesięcznie.
Tworzymy wykresy punktowe (scatter plots) dla zmiennych liczbowych, takich jak frekwencja, oraz poprzedni wynik egzaminu w odniesieniu do wyniku egzaminu.
scatter_plots <- list()
numeric_vars <- c("Attendance", "Previous_Scores")
for (var in numeric_vars) {
scatter_plot <- ggplot(czynniki3, aes_string(x = var, y = "Exam_Score")) +
geom_point(color = "#0c4c8a") +
labs(title = paste("Scatter Plot of Exam_Score vs", var), x = var, y = "Exam Score") +
theme_minimal()
scatter_plots[[var]] <- scatter_plot
}
scatter_plots[["Attendance"]] | scatter_plots[["Previous_Scores"]]
Na podstawie wykresu punktowego wynik egzaminu, a frekwencja możemy zauważyć pewien trend, który ukazuje, że im większa frekwencja tym średnio wynik egzaminu był wyższy. Dodatkowo możemy zauważyć pewne odstające wartości, które osiągał znacząco większe wyniki od średniej.
Na podstawie wykresu punktowego wynik egzaminu, a poprzedni wynik egzaminu możemy zauważyć, że wyniki rozkładają się w porównywalnie w ten sam sposób, nie zależnie od poprzedniego wyniku egzaminu.
Obliczamy podstawowe statystyki, między innymi takie jak, minimum, maksimum, mediana, kwartyle, średnia i odchylenie standardowe.
# Obliczanie poszczególnych statystyk (testowe bo inaczej nie działało)
Min <- min(czynniki3$Exam_Score, na.rm = TRUE)
Max <- max(czynniki3$Exam_Score, na.rm = TRUE)
Kwartyl_dolny <- quantile(czynniki3$Exam_Score, 0.25, na.rm = TRUE)
Mediana <- median(czynniki3$Exam_Score, na.rm = TRUE)
Kwartyl_gorny <- quantile(czynniki3$Exam_Score, 0.75, na.rm = TRUE)
Srednia <- mean(czynniki3$Exam_Score, na.rm = TRUE)
Odch_std <- sd(czynniki3$Exam_Score, na.rm = TRUE)
IQR_value <- IQR(czynniki3$Exam_Score, na.rm = TRUE)
Skosnosc <- skewness(czynniki3$Exam_Score, na.rm = TRUE)
Kurtoza_value <- kurtosis(czynniki3$Exam_Score, na.rm = TRUE)
Odch_std_pct <- (Odch_std / Srednia) * 100
Odch_cwiartkowe_pct <- (IQR_value / Mediana) * 100
Odchylenie_cwiartkowe <- IQR_value / 2
statystyki <- data.frame(
Min = round(Min, 3),
Max = round(Max, 3),
"Kwartyl_dolny" = round(Kwartyl_dolny, 3),
Mediana = round(Mediana, 3),
"Kwartyl_górny" = round(Kwartyl_gorny, 3),
Średnia = round(Srednia, 3),
"Odchylenie_standardowe" = round(Odch_std, 3),
IQR = round(IQR_value, 3),
"Skośność" = round(Skosnosc, 3),
"Kurtoza" = round(Kurtoza_value, 3),
"Odchylenie_standardowe%" = paste0(round(Odch_std_pct, 3), "%"),
"Odchylenie_ćwiartkowe%" = paste0(round(Odch_cwiartkowe_pct, 3), "%"),
"Odchylenie_ćwiartkowe" = round(Odchylenie_cwiartkowe, 3)
)
statystyki <- t(statystyki)
statystyki <- as.data.frame(statystyki)
colnames(statystyki) <- c("Wartości")
statystyki$Statystyki <- rownames(statystyki)
rownames(statystyki) <- NULL
kable(statystyki, format = "html", caption = "Statystyki opisowe dla zmiennej 'Exam_Score'") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = T)
| Wartości | Statystyki |
|---|---|
| 56 | Min |
| 100 | Max |
| 65 | Kwartyl_dolny |
| 67 | Mediana |
| 69 | Kwartyl_górny |
| 67.217 | Średnia |
| 3.835 | Odchylenie_standardowe |
| 4 | IQR |
| 1.554 | Skośność |
| 13.062 | Kurtoza |
| 5.705% | Odchylenie_standardowe. |
| 5.97% | Odchylenie_ćwiartkowe. |
| 2 | Odchylenie_ćwiartkowe |
Po przeprowadzonej analizie statystyki opisowej możemy zobaczyć, że średnia oraz mediana są zbliżone około 67. Pomimo tego skośność wychodzi prawostronna, co oznacza, że występują wartości odstające dążące wyniku 100. Dodatkowo, kurtoza potwierdza spiczastość samego rozkładu
Tworzymy macierz korelacji, by zbadać, jak różne czynniki są ze sobą powiązane, aby zidentyfikować silne korelacje, które mogą wskazywać na potencjalne przyczyny wysokich lub niskich wyników egzaminów.
cor_matrix <- cor(czynniki_kor, use = "complete.obs")
corrplot(cor_matrix, method = "color", type = "upper", order = "hclust",
tl.col = "black", tl.srt = 45)
Analizujemy zależność korelacji Liczby Godzin Nauki, wobec Wyniu Egazminu (Przyjęty poziom istotności alfa = 0,05). Do analizy zastosujemy test Pearsona.
ggscatterstats(
data = czynniki3,
x = Hours_Studied,
y = Exam_Score,
title = "Korelacja: Wynik egzaminu a liczba godzin nauki",
xlab = "Liczba godzin nauki",
ylab = "Wynik egzaminu",
ggtheme = ggplot2::theme_minimal()
)
Choć ostateczny wynik był spodziewany, to analiza wykazała, że liczba godzin nauki ma istotny wpływ na wynik egazminu, współczynnik p<0,05 (przyjęty poziom istotności)
Analizujemy zależność korelacji Wcześniejszego Wyniku, wobec Wyniu Egazminu (Przyjęty poziom istotności alfa = 0,05). Do analizy zastosujemy test Pearsona.
# Korelacja Exam_Score vs Previous_Scores
ggscatterstats(
data = czynniki3,
x = Previous_Scores,
y = Exam_Score,
title = "Korelacja: Wynik egzaminu a wcześniejsze wyniki",
xlab = "Poprzednie wyniki",
ylab = "Wynik egzaminu",
ggtheme = ggplot2::theme_minimal()
)
Przeprowadzony test wykazał, że wcześniejszy wynik ma istotny wpływ na wynik egzaminu, współczynnik p<0,05 (przyjęty poziom istotności).
Analizujemy zależność liniową Wyniku Egzaminu wobec Czasu Aktywności Fizycznej, oraz Średniego Czasu Snu (Przyjęty poziom istotności alfa = 0,05).
#Tworzymy model regresji liniowej z Physical_Activity i Sleep_Hours jako zmiennymi objaśniającymi
model1 <- lm(Exam_Score ~ Physical_Activity + Sleep_Hours, data = czynniki3)
plot1 <- ggcoefstats(
model1,
title = "Wpływ aktywności fizycznej i snu na wynik egzaminu",
xlab = "Współczynniki regresji",
ggtheme = ggplot2::theme_minimal()
)
# Rysowanie wykresu
print(plot1)
Przeprowadzona zależność liniowa wykazała, że aktywność fizyczna ma istotny wpływ na wynik egzaminu, współczynnik p<0,05 (przyjęty poziom istotności). Z drugiej strony czas snu jest nie istonty na wynik egzaminu, współczynnik p>0,05 (przyjęty poziom istotności)
Analizujemy zależność korelacji Frekwencji, wobec Wyniu Egazminu (Przyjęty poziom istotności alfa = 0,05). Do analizy zastosujemy test Pearsona.
ggscatterstats(
data = czynniki3,
x = Attendance,
y = Exam_Score,
title = "Korelacja: Wynik egzaminu a frekwencja",
xlab = "Frekwencja (%)",
ylab = "Wynik egzaminu",
ggtheme = ggplot2::theme_minimal()
)
Przeprowadzony test wykazał, że frekwencja ma istotny wpływ na wynik egzaminu, współczynnik p<0,05(przyjęty poziom istotności).
Porównujemy wielkości efektów dla Wyniu Egazminu, ze względu na płeć (Przyjęty poziom istotności alfa = 0,05). Do analizy wykorzystamy statystyke g Hedge’a.
ggbetweenstats(
data = czynniki3,
x = Gender,
y = Exam_Score,
title = "Porównanie wyników egzaminu wg płci",
xlab = "Płeć",
ylab = "Wynik egzaminu",
ggtheme = ggplot2::theme_minimal()
)
Przeprowadzony test wykazał, że wynik egzaminu, nie jest zależny od płci, współczynnik p>0,05 (przyjęty poziom istotności).
Wykonujemy test porównania średnich dla Wyniu Egazminu, ze względu na Dostęp do Zasobów Edukacyjnych (Przyjęty poziom istotności alfa = 0,05). Do analizy wykorzystamy metodę Gamesa-Howella.
ggbetweenstats(
data = czynniki3,
x = Access_to_Resources,
y = Exam_Score,
title = "Porównanie wyników egzaminu wg dostępu do zasobów edukacyjnych",
xlab = "Zasoby edukacyjne",
ylab = "Wynik egzaminu",
ggtheme = ggplot2::theme_minimal()
)
Przeprowadzony test wykazał, że wynik egzaminu, jest zależny od poziomu dostępu do zasobów edukacyjnych, współczynnik p<0,05 (przyjęty poziom istotności).
Wykonujemy test porównania średnich dla Wyniu Egazminu, ze względu na Poziom Zaangażowania Rodziców (Przyjęty poziom istotności alfa = 0,05). Do analizy wykorzystamy metodę Gamesa-Howella.
ggbetweenstats(
data = czynniki3,
x = Parental_Involvement,
y = Exam_Score,
title = "Porównanie wyników egzaminu wg poziomu zaagnażowania rodziców",
xlab = "Poziom zaangażowania rodziców",
ylab = "Wynik egzaminu",
ggtheme = ggplot2::theme_minimal()
)
Przeprowadzony test wykazał, że wynik egzaminu, jest zależny od poziomu zaangażowania rodziców, współczynnik p<0,05 (przyjęty poziom istotności).
Celem projektu była analiza czynników wpływających na wyniki egzaminów uczniów. W ramach projektu przeprowadziliśmy kompleksową analizę danych zawierających informacje na temat takich zmiennych jak między innymi liczba godzin snu, czas poświęcony na naukę, rodzaj szkoły, czy na przykład wpływ rówieśników i motywacja ucznia.
Proces analizy obejmował kilka kluczowych etapów:
Data Wrangling: Na początek zajęliśmy się przygotowaniem danych. Wczytaliśmy dane z dostępnych źródeł i sprawdziliśmy ich strukturę, aby upewnić się, że zawierają one wszystkie niezbędne informacje. Etap ten obejmował także identyfikację zmiennych, które miały istotny wpływ na wyniki egzaminów. Przeanalizowaliśmy dane pod kątem ich typu, rozkładu oraz obecności błędów w strukturze.
Czyszczenie Danych: Po wstępnym przygotowaniu danych, przystąpiliśmy do oczyszczania ich z błędów i braków. Wykorzystaliśmy techniki imputacji brakujących danych, takie jak imputacja metodą “mice”, co pozwoliło nam uzyskać kompletny zbiór danych. Ponadto, usunęliśmy wszelkie niezgodności i błędne wartości, co poprawiło jakość analizy.
Wizualizacja: W kolejnym kroku skoncentrowaliśmy się na wizualizacji danych. Użyliśmy wykresów pudełkowych, histogramów, wykresów słupkowych, kołowych, czy punktowych, aby zobrazować rozkład danych i zależności pomiędzy poszczególnymi zmiennymi. Wizualizacje te pozwoliły na łatwiejsze zrozumienie kluczowych informacji, takich jak rozkład wyników egzaminu czy różnice w wynikach między uczniami o różnym poziomie motywacji i dostępie do zasobów edukacyjnych.
Analiza Opisowa: W ramach analizy opisowej obliczyliśmy podstawowe miary statystyczne, takie jak średnia, mediana, odchylenie standardowe oraz kwartyle dla wyniku egzaminu. Zauważyliśmy, że wyniki uczniów rozkładają się dość równomiernie, a średni wynik egzaminu wynosi około 67%. Przeanalizowaliśmy również skośność i kurtozę, co pozwoliło na lepsze zrozumienie rozkładu wyników wśród uczniów.
Wnioskowanie Statystyczne: Na podstawie wyników analizy opisowej, przystąpiliśmy do wnioskowania statystycznego. Sprawdziliśmy zależności między różnymi czynnikami a wynikami egzaminów. Zauważyliśmy, że czynniki takie jak liczba godzin snu, motywacja uczniów, wsparcie ze strony rodziców oraz dostępność zasobów edukacyjnych mają znaczący wpływ na wyniki. Wykorzystaliśmy testy statystyczne, aby potwierdzić, że obserwowane różnice są istotne i nie wynikają z przypadkowych fluktuacji w danych.
Wyniki naszej analizy pokazują, że wyniki egzaminów zależą od wielu czynników. Kluczowymi zmiennymi, które mają istotny wpływ na wyniki egzaminów, są liczba godzin nauki, wcześniejsze wyniki, aktywność fizyczna, frekwencja, dostęp do zasobów edukacyjnych oraz zaangażowanie rodziców. Z kolei czas snu i płeć nie mają bezpośredniego wpływu na wyniki.