Najpierw ustal, co łączysz: wiersze czy kolumny
„Połączyć bazy” może znaczyć dwie zupełnie różne operacje. Od nich zależy, co musi się zgadzać.
| Doklejanie wierszy | Doklejanie kolumn | |
|---|---|---|
| Kiedy | Ta sama ankieta, różne osoby: dwa formularze, dwie uczelnie, wersja papierowa i online | Te same osoby, różne zmienne: pomiar 1 i pomiar 2, ankieta i wyniki testu |
| Co musi się zgadzać | Nazwy kolumn, typy zmiennych i kody odpowiedzi | Identyfikator osoby, zapisany identycznie w obu plikach |
| R | rbind() albo dplyr::bind_rows() | merge(…, by = "kod") albo dplyr::left_join() |
| SPSS | Data > Merge Files > Add Cases | procedura Add Variables |
| Typowy błąd | „Płeć” jako K/M w jednym pliku i kobieta/mężczyzna w drugim | Kod „ab12” w jednym pliku i „AB12 ” w drugim |
Docelowo każdy wiersz to jedna osoba, a każda kolumna to jedna zmienna (Wickham, 2014). Jeśli pomiary powtarzane chcesz analizować modelem mieszanym, potrzebny będzie też format długi. Zasady budowy samej bazy, nazw zmiennych i kodowania opisuje pełny poradnik jak przygotować bazę danych do analizy. Tutaj zajmiemy się tylko łączeniem.
Doklejanie wierszy: ujednolicić, oznaczyć, skleić
Zanim skleisz pliki, sprawdź trzy rzeczy:
- Nazwy kolumn. „Płeć”, „plec” i „Plec” to dla programu trzy różne zmienne. Zmień nazwy według jednej książki kodowej.
- Kody odpowiedzi. Jeśli jeden formularz zwraca tekst, a drugi liczby, najpierw zrekoduj oba pliki tak samo. Jak to zrobić z eksportem z ankiety online, pokazuje wpis dane z Google Forms i LimeSurvey.
- Typy zmiennych. W SPSS zmiennej liczbowej nie połączysz z tekstową, a zmienne tekstowe o różnej zdefiniowanej szerokości też trafią do listy Unpaired Variables (IBM Corp., b.d.-a). Ta sama procedura ma opcję Indicate case source as variable. Dodaje ona zmienną, która mówi, z którego pliku pochodzi wiersz.
Taką zmienną dodaj zawsze, także w R. W naszym przykładzie (dane symulowane) połączyliśmy 80 osób z pierwszego formularza i 60 z drugiego. Drugi formularz miał inne nazwy kolumn i płeć zapisaną słowami. Po ujednoliceniu baza ma 140 wierszy, a kolumna zrodlo pozwala sprawdzić, czy grupy z obu formularzy nie różnią się czymś nieoczekiwanym. Zanim połączysz pliki eksportowane z różnych programów, sprawdź też kodowanie znaków, bo polskie litery w nazwach i etykietach psują się najczęściej właśnie tu.
Doklejanie kolumn: wszystko zależy od kodu uczestnika
W badaniu z dwoma pomiarami osoby zwykle same tworzą kod, np. z dwóch pierwszych liter imienia matki i dnia urodzenia. Taki kod pozwala połączyć odpowiedzi tej samej osoby bez zbierania nazwisk (Yurek i in., 2008). Pamiętaj, że to pseudonimizacja, a nie anonimizacja. Schnell i in. (2010) zwracają uwagę, że przez błędy w kodach wiele przypadków się gubi, a to może zniekształcić wyniki. Proponują więc kody z większą liczbą elementów i dopasowywanie przybliżone za pomocą odległości Levenshteina, czyli liczby pojedynczych zmian znaków.
W przykładzie pierwszy pomiar wypełniło 140 osób, a w pliku z drugiego pomiaru było 114 wierszy. Tak przebiegało łączenie:
| Krok | Co zrobiono | Wynik |
|---|---|---|
| 1 | Łączenie „na surowo” | 97 par |
| 2 | Usunięcie spacji i zamiana liter na wielkie | 111 par |
| 3 | Wykrycie duplikatów: dwie osoby wysłały formularz dwa razy | 112 osób w pomiarze 2 |
| 4 | Trzy kody bez pary, każdy różni się od kodu z pomiaru 1 jednym znakiem (np. XC05 i SC05) – sprawdzone i poprawione ręcznie | 0 kodów bez pary |
| 5 | Łączenie z zachowaniem wszystkich osób z pomiaru 1 | 140 osób, 112 z oboma pomiarami |
Gdyby skończyć na kroku 1, z analizy wypadłoby 15 osób. Do tego 2 osoby z drugiego pomiaru zostałyby policzone podwójnie, gdyby nie sprawdzić duplikatów po ujednoliceniu kodów. Kandydatów z odległością 1 nie poprawiaj automatycznie. Porównaj ich odpowiedzi demograficzne, a decyzje zapisz w dzienniku zmian.
W SPSS to samo robi procedura Add Variables z dopasowaniem według wartości klucza. Zmienna kluczowa musi mieć tę samą nazwę i ten sam typ w obu plikach, a pliki muszą być posortowane według klucza. Program może je posortować sam, jeśli zostawisz zaznaczoną opcję Sort files by key values before merging (IBM Corp., b.d.-b). Ujednolicenie kodów i kontrolę duplikatów i tak musisz wykonać wcześniej.
Na koniec sprawdź, kto odpadł. W przykładzie 28 osób nie wypełniło drugiego pomiaru. Miały one w pierwszym pomiarze wyższy stres (M = 3.24, SD = 0.51) niż osoby, które zostały (M = 3.01, SD = 0.57), t(45.39) = 2.11, p = .041, różnica 0.23, 95% CI [0.01, 0.45]. To informacja o utracie uczestników, którą trzeba podać w pracy. Co dalej z brakującymi pomiarami, wyjaśnia wpis braki danych w ankiecie.
Lista kontrolna po połączeniu
- Liczba wierszy po połączeniu zgadza się z oczekiwaną. Jeśli wzrosła, masz duplikaty kodów.
- Każdy kod występuje w każdym pliku najwyżej raz.
- Znasz liczbę osób bez pary w każdym pliku i wiesz, dlaczego jej nie mają.
- Rozkłady kluczowych zmiennych przed połączeniem i po nim są takie same.
- Pliki surowe zostały nietknięte, a całe łączenie da się powtórzyć skryptem (Broman i Woo, 2018). Zapisz wynik w formacie, który łatwo otworzyć, np. CSV.
Jak to opisać w pracy
W części o procedurze napisz, jak łączono dane, ile osób dopasowano i ile odpadło. Recenzent powinien móc odtworzyć liczebności z tabel.
Jeśli pracujesz w R pierwszy raz, zacznij od wpisu R dla początkujących. Jeśli bazy są duże albo kody bardzo niespójne, możesz zlecić sprawdzenie łączenia w ramach oferty analiz statystycznych dla studentów. Opis procedury i jej skutków musisz jednak rozumieć sam(a).
Łączenie baz w R krok po kroku
Kod tworzy symulowane bazy z dwóch formularzy i z dwóch pomiarów, a potem łączy je tak jak w tekście: dokleja wiersze, ujednolica kody, szuka duplikatów i podobnych kodów (funkcja adist() liczy odległość Levenshteina) i sprawdza, kto odpadł. Wystarczy podstawowa instalacja R. Przy swoich danych zacznij od wczytania plików, np. read.csv(), i przejdź od razu do kroku 1.
1. Doklejanie wierszy i kolumn z kontrolą kodów
R
# Łączenie dwóch baz z ankiet (dane symulowane, set.seed(1480))
set.seed(1480)
litery <- function(n) paste0(sample(LETTERS[c(1:22, 26)], n, TRUE), sample(LETTERS[c(1:22, 26)], n, TRUE))
# Kod uczestnika: dwie pierwsze litery imienia matki + dzień urodzenia (dwie cyfry)
kody <- unique(paste0(litery(400), sprintf("%02d", sample(1:31, 400, TRUE))))[1:140]
# ---- A. Doklejanie wierszy: ta sama ankieta zebrana dwoma formularzami (dwa kierunki studiów)
f1 <- data.frame(kod = kody[1:80], plec = sample(c("K", "M"), 80, TRUE, c(.7, .3)), stres_1 = round(rnorm(80, 3.1, .6), 2))
f2 <- data.frame(Kod = paste0("ab", 1:60), Płeć = sample(c("kobieta", "mężczyzna"), 60, TRUE, c(.65, .35)),
stres = round(rnorm(60, 3.0, .6), 2), check.names = FALSE)
names(f2) <- c("kod", "plec", "stres_1") # te same nazwy kolumn
f2$plec <- ifelse(f2$plec == "kobieta", "K", "M") # te same kody odpowiedzi
f1$zrodlo <- "formularz_1"; f2$zrodlo <- "formularz_2" # skąd pochodzi wiersz
razem <- rbind(f1, f2)
dim(razem); table(razem$zrodlo, razem$plec)
# ---- B. Doklejanie kolumn: pomiar 1 (październik) i pomiar 2 (styczeń) tych samych osób
p1 <- data.frame(kod = kody, stres_1 = round(rnorm(140, 3.1, .6), 2))
wraca <- sample(140, 112) # 112 osób wypełniło też pomiar 2
p2 <- data.frame(kod = kody[wraca], stres_2 = round(p1$stres_1[wraca] - 0.2 + rnorm(112, 0, .45), 2))
# typowe problemy w drugiej bazie
p2$kod[1:9] <- tolower(p2$kod[1:9]) # małe litery
p2$kod[10:14] <- paste0(" ", p2$kod[10:14]) # spacja na początku
p2$kod[15:17] <- sub("^(.)", "X", p2$kod[15:17]) # literówka w pierwszym znaku
p2 <- rbind(p2, p2[c(20, 21), ]) # dwie osoby wysłały formularz dwa razy
nrow(p2)
# Krok 1: porównanie „na surowo”
nrow(merge(p1, p2, by = "kod"))
# Krok 2: ujednolicenie kodów
czysc <- function(x) toupper(gsub("[[:space:]]", "", x))
p1$kod <- czysc(p1$kod); p2$kod <- czysc(p2$kod)
nrow(merge(p1, p2, by = "kod"))
# Krok 3: duplikaty
sum(duplicated(p1$kod)); sum(duplicated(p2$kod))
p2[p2$kod %in% p2$kod[duplicated(p2$kod)], ]
p2 <- p2[!duplicated(p2$kod), ] # zostaw pierwsze zgłoszenie
nrow(p2)
# Krok 4: kody bez pary i podobne kody (odległość Levenshteina = 1)
bez_pary <- setdiff(p2$kod, p1$kod); bez_pary
odl <- adist(bez_pary, setdiff(p1$kod, p2$kod))
kandydaci <- data.frame(kod_p2 = bez_pary,
najblizszy_p1 = setdiff(p1$kod, p2$kod)[apply(odl, 1, which.min)],
odleglosc = apply(odl, 1, min))
kandydaci
# poprawki zatwierdzone ręcznie (w każdym przypadku jeden kandydat z odległością 1)
p2$kod[match(kandydaci$kod_p2, p2$kod)] <- kandydaci$najblizszy_p1
# Krok 5: łączenie i kontrola
pelne <- merge(p1, p2, by = "kod", all.x = TRUE) # wszyscy z pomiaru 1
dim(pelne); sum(!is.na(pelne$stres_2)); sum(is.na(pelne$stres_2))
# Czy osoby, które odpadły, różnią się w pomiarze 1?
pelne$odpadl <- factor(ifelse(is.na(pelne$stres_2), "odpadli", "zostali"))
round(tapply(pelne$stres_1, pelne$odpadl, mean), 2); round(tapply(pelne$stres_1, pelne$odpadl, sd), 2)
t.test(stres_1 ~ odpadl, data = pelne)
round(100 * mean(!is.na(pelne$stres_2)), 1) # odsetek osób z oboma pomiarami
round(diff(rev(tapply(pelne$stres_1, pelne$odpadl, mean))), 2) # różnica: odpadli − zostaliWynik w R
[1] 140 4
K M
formularz_1 59 21
formularz_2 41 19
[1] 114
[1] 97
[1] 111
[1] 0
[1] 2
kod stres_2
20 LC18 1.40
21 BZ20 1.72
201 LC18 1.40
211 BZ20 1.72
[1] 112
[1] "XC05" "XS31" "XZ02"
kod_p2 najblizszy_p1 odleglosc
1 XC05 SC05 1
2 XS31 LS31 1
3 XZ02 SZ02 1
[1] 140 3
[1] 112
[1] 28
odpadli zostali
3.24 3.01
odpadli zostali
0.51 0.57
Welch Two Sample t-test
data: stres_1 by odpadl
t = 2.1052, df = 45.386, p-value = 0.04084
alternative hypothesis: true difference in means between group odpadli and group zostali is not equal to 0
95 percent confidence interval:
0.01003528 0.45157186
sample estimates:
mean in group odpadli mean in group zostali
3.242857 3.012054
[1] 80
odpadli
0.23Bibliografia oprogramowania
Wyniki na tej stronie pochodzą z uruchomienia pokazanego kodu w R 4.5.3 (funkcje rbind(), merge(), duplicated() i t.test() z pakietów base i stats oraz adist() z pakietu utils).
- R: R Core Team. (2026). R: A language and environment for statistical computing (Version 4.5.3) [Computer software]. R Foundation for Statistical Computing. https://www.R-project.org/
Najczęstsze pytania
Jak połączyć dane z pomiaru przed i po, gdy uczestnicy wpisali kod?
Ujednolicić zapis kodów (usuń spacje, zamień litery na wielkie), usuń powtórzone zgłoszenia i połącz pliki według kodu, zachowując wszystkie osoby z pierwszego pomiaru. Kody bez pary porównaj z kodami z drugiego pliku. Kod różniący się jednym znakiem to częsta literówka, ale poprawiaj ją dopiero po ręcznym sprawdzeniu.
Dlaczego po połączeniu baz mam więcej wierszy niż osób?
Najczęściej dlatego, że ten sam kod występuje w jednym z plików więcej niż raz, np. ktoś wysłał formularz dwa razy. Każdy taki duplikat mnoży wiersze po połączeniu. Przed łączeniem sprawdź duplikaty w każdym pliku osobno, w R funkcją duplicated().
Czym się różni Add Cases od Add Variables w SPSS?
Add Cases dokleja wiersze: łączy pliki z tymi samymi zmiennymi i innymi osobami. Add Variables dokleja kolumny: łączy pliki z tymi samymi osobami i innymi zmiennymi, dopasowując je według kolejności albo zmiennej kluczowej, która musi mieć tę samą nazwę i typ w obu plikach (IBM Corp., b.d.-a, b.d.-b).
Powiązane hasła
Przeczytaj też
Jak przygotować bazę danych do analizy
Układ bazy, nazwy zmiennych, kodowanie ankiety, braki, pułapki Excela, widok zmiennych w SPSS i kontrola jakości – z szablonem .xlsx, .sav i .csv do pobrania.
Czytaj →PoradnikDane z Google Forms i LimeSurvey: kodowanie do SPSS i R
Eksport, nazwy zmiennych, rekodowanie Likerta, pozycje odwrócone, wielokrotny wybór i braki – krok po kroku, z kodem R i wzorem książki kodowej.
Czytaj →PoradnikBraki danych w ankiecie – co zrobić?
Jak policzyć braki, kiedy wystarczy reguła proporcjonalna, jak sprawdzić osoby, które przerwały ankietę, i jak opisać braki w pracy.
Czytaj →Bazy z dwóch pomiarów nie chcą się połączyć?
Sprawdzimy kody uczestników, połączymy pliki skryptem i wyjaśnimy każdy krok tak, żebyś umiał(a) opisać procedurę w pracy.
Oferta dla studentówWyceń analizęBibliografia i dalsza literatura naukowa (APA 7)
- Broman, K. W., & Woo, K. H. (2018). Data organization in spreadsheets. The American Statistician, 72(1), 2–10. https://doi.org/10.1080/00031305.2017.1375989 ● Otwarty dostęp: pełny tekst
- IBM Corp. (b.d.). Add Cases. IBM SPSS Statistics 31.0.0 documentation. Pobrano 26 października 2026 z https://www.ibm.com/docs/en/spss-statistics/31.0.0?topic=files-add-cases ● Otwarty dostęp
- IBM Corp. (b.d.). Add Variables. IBM SPSS Statistics 31.0.0 documentation. Pobrano 26 października 2026 z https://www.ibm.com/docs/en/spss-statistics/31.0.0?topic=files-add-variables ● Otwarty dostęp
- Schnell, R., Bachteler, T., & Reiher, J. (2010). Improving the use of self-generated identification codes. Evaluation Review, 34(5), 391–418. https://doi.org/10.1177/0193841x10387576
- Wickham, H. (2014). Tidy data. Journal of Statistical Software, 59(10), 1–23. https://doi.org/10.18637/jss.v059.i10 ● Otwarty dostęp
- Yurek, L. A., Vasey, J., & Sullivan Havens, D. (2008). The use of self-generated identification codes in longitudinal research. Evaluation Review, 32(5), 435–452. https://doi.org/10.1177/0193841x08316676
Cytowania BibTeX
@article{broman2018data, author={Broman, Karl W. and Woo, Kara H.}, title={{Data organization in spreadsheets}}, journal={The American Statistician}, year={2018}, volume={72}, number={1}, pages={2--10}, doi={10.1080/00031305.2017.1375989}}@misc{ibmndaddcases, author={{IBM Corp.}}, title={{Add Cases}}, howpublished={IBM SPSS Statistics 31.0.0 documentation}, publisher={IBM}, url={https://www.ibm.com/docs/en/spss-statistics/31.0.0?topic=files-add-cases}}@misc{ibmndaddvariables, author={{IBM Corp.}}, title={{Add Variables}}, howpublished={IBM SPSS Statistics 31.0.0 documentation}, publisher={IBM}, url={https://www.ibm.com/docs/en/spss-statistics/31.0.0?topic=files-add-variables}}@article{schnell2010improving, author={Schnell, Rainer and Bachteler, Tobias and Reiher, Jörg}, title={{Improving the use of self-generated identification codes}}, journal={Evaluation Review}, year={2010}, volume={34}, number={5}, pages={391--418}, doi={10.1177/0193841x10387576}}@article{wickham2014tidy, author={Wickham, Hadley}, title={{Tidy data}}, journal={Journal of Statistical Software}, year={2014}, volume={59}, number={10}, pages={1--23}, doi={10.18637/jss.v059.i10}}@article{yurek2008use, author={Yurek, Leo A. and Vasey, Joseph and Sullivan Havens, Donna}, title={{The use of self-generated identification codes in longitudinal research}}, journal={Evaluation Review}, year={2008}, volume={32}, number={5}, pages={435--452}, doi={10.1177/0193841x08316676}}