Orientujemy się gdzie jesteśmy. Można odpalić też eksploratora
Windows i stamtąd sięgnąć po ścieżkę, wklejając ją do polecenia
(funkcji): setwd("...")
getwd() # orientujemy się gdzie jesteśmy
## [1] "C:/Users/Maluchnik/Documents/Statystyka1_R/materialy/Zaj_3"
# setwd(...) always a good choice...
# \ (backslash - Windows) vs / (slash - reszta świata)
list.files() # == dir()
## [1] "dane" "grafika" "rsconnect" "SQL_query_in_R.R"
## [5] "styles.css" "Zaj3 - Copy.html" "Zaj3.html" "Zaj3.Rmd"
# opowiedzieć o alternatywnych sposobach ustawiania working directory poprzez wyklikanie prawego dolnego okna ->
# Ciekawostka - alternatywa dla ukośników:
file.path("C:", "Users", "Maluchnik", "Documents")
## [1] "C:/Users/Maluchnik/Documents"
Lista baz danych zawartych w pakiecie {dataset} ujawni
nam się po użyciu polecenia: data().
Lista baz danych z wszystkich aktywnych pakietów (nie tylko
{dataset}) odpalamy poleceniem:
data(package = .packages(all.available = TRUE))
# z poprzednich zajęć znamy co najmniej jedną z poniższych ramek
head(iris, 3)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
head(mtcars, 3)
## mpg cyl disp hp drat wt qsec vs am gear carb
## Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
## Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
## Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
# niektóre znajdują się w innych pakietach, zatem najpierw wczytujemy pakiet go zawierający
library(ggplot2)
# a następnie
head(diamonds, 3) # -> nie ma w środowisku
## # A tibble: 3 × 10
## carat cut color clarity depth table price x y z
## <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
## 1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
## 2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
## 3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
data(diamonds) # -> Promise? Promise what?
diamonds[1:5,1:5] # -> jest po pierwszej próbie użycia zbioru :D
## # A tibble: 5 × 5
## carat cut color clarity depth
## <dbl> <ord> <ord> <ord> <dbl>
## 1 0.23 Ideal E SI2 61.5
## 2 0.21 Premium E SI1 59.8
## 3 0.23 Good E VS1 56.9
## 4 0.29 Premium I VS2 62.4
## 5 0.31 Good J SI2 63.3
# Inny przykład ...
dane_KolorOczuIWlosow = HairEyeColor # studentów statystki (kobiet i mężczyzn)
str(dane_KolorOczuIWlosow)
## 'table' num [1:4, 1:4, 1:2] 32 53 10 3 11 50 10 30 10 25 ...
## - attr(*, "dimnames")=List of 3
## ..$ Hair: chr [1:4] "Black" "Brown" "Red" "Blond"
## ..$ Eye : chr [1:4] "Brown" "Blue" "Hazel" "Green"
## ..$ Sex : chr [1:2] "Male" "Female"
iris <- iris
mtcars <- mtcars
Najpopularniejszy format danych wczytywanych do R to dane tekstowe. Jest to format prosty i uniwersalny - cała informacja zakodowana jest w znakach widocznych z poziomu Notepad’a, a pliki da się odczytać w różnych programach na każdym dostępnym systemie operacyjnym.
Klasyfikacja typów plików może zostać dokonana na podstawie sposobu organizacji kolumn, mamy zatem:
pliki rozdzielane separatorem (średnik, przecinek, znak pionowej linii, etc.)
pliki o stałej szerokości kolumn (fixed width column)
Zawsze, używając po raz pierwszy jakiejś funkcji, przejrzyjmy
wcześniej jej dokumentację ?read.table (lub
help(package="read.table"). read.table jest to
uogólniona funkcja do wczytywania wielu typów formatów plików
tekstowych.
miasta <- read.table("dane/cities.txt", # nazwa pliku wraz z rozszerzeniem
header = TRUE, # pierwsza kolumna jako nagłówek?
sep = ",", # separator kolumn
dec = ".") # znak oddzielający część całkowitą od dziesiętnej
Sprawdzenie danych (i utrwalenie podstawowych funkcji rozruchowych - do rozeznania się w ramce bez niepotrzebnego print’owania w konsoli)
is.data.frame(miasta) # czy to data.frame?
## [1] TRUE
head(miasta,3) # wyrzucenie do konsoli pierwszych 3 wierszy
## Country City AccentCity Region Population Latitude
## 1 ad andorra la vella Andorra la Vella 07 20430 42.50000
## 2 ad canillo Canillo 02 3292 42.56667
## 3 ad encamp Encamp 03 11224 42.53333
## Longitude
## 1 1.516667
## 2 1.600000
## 3 1.583333
tail(miasta,3) # wyrzucenie do konsoli ostatnich 3 wierszy
## Country City AccentCity Region Population Latitude
## 47978 zw shurugwi Shurugwi 07 17107 -19.66667
## 47979 zw victoria falls Victoria Falls 00 36702 -17.93333
## 47980 zw zvishavane Zvishavane 07 79876 -20.33333
## Longitude
## 47978 30.00000
## 47979 25.83333
## 47980 30.03333
is.numeric(miasta$Population) # upewnienie się co do typu danych konkretnej zmiennej
## [1] TRUE
str(miasta) # struktura danych
## 'data.frame': 47980 obs. of 7 variables:
## $ Country : chr "ad" "ad" "ad" "ad" ...
## $ City : chr "andorra la vella" "canillo" "encamp" "la massana" ...
## $ AccentCity: chr "Andorra la Vella" "Canillo" "Encamp" "La Massana" ...
## $ Region : chr "07" "02" "03" "04" ...
## $ Population: int 20430 3292 11224 7211 15854 2553 8020 603687 1137376 543942 ...
## $ Latitude : num 42.5 42.6 42.5 42.5 42.5 ...
## $ Longitude : num 1.52 1.6 1.58 1.52 1.53 ...
summary(miasta) # podsumowanie zmiennych
## Country City AccentCity Region
## Length:47980 Length:47980 Length:47980 Length:47980
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
## Population Latitude Longitude
## Min. : 7 Min. :-54.80 Min. :-179.50
## 1st Qu.: 3732 1st Qu.: 14.65 1st Qu.: -41.68
## Median : 10779 Median : 39.13 Median : 19.90
## Mean : 47720 Mean : 30.62 Mean : 14.67
## 3rd Qu.: 27990 3rd Qu.: 47.87 3rd Qu.: 58.41
## Max. :31480498 Max. : 78.93 Max. : 179.32
Czy moglibyśmy opuścić argumenty funkcji read.table?
miasta2 <- read.table("dane/cities.txt")
Nie działa, bo domyślnie argumenty uzupełnione w następujący sposób:
header = FALSE, sep = "", dec = "."
Zajrzyjmy do dokumentacji: ?read.csv. Jest to funkcja z
rodziny read.table służąca do wczytywania danych z pliku
csv (tekstowy rozdzielany przecinkami)
daneusa <- read.csv("dane/daneusa.csv") # wczytanie
Domyślne założenia funkcji:
separator -> sep = ","
znak dziesiętny -> dec = "."
header = FALSE -> plik zawiera nazwy kolumn w
pierwszym wierszu (nagłówek)
jeśli jest inaczej, można użyć odpowiednich dodatkowych argumentów funkcji:
daneusa <- read.csv("dane/daneusa.csv",
sep = ",",
dec = ".",
header = TRUE)
Jest też funkcja read.csv2(), (stworzona dla Europy
kontynentalnej), która ma inne domyślne parametry tj.:
sep = " oraz ", dec = ",".
Co by się stało, gdybyśmy skorzystali z niej do wczytania tego pliku?
daneusa <- read.csv2("dane/daneusa.csv")
warto zwrócić na to uwagę w Global Environment. Inny separator kolumn spowodował, że R nie rozróżnia kolumn
Wróćmy więc do poprzedniej funkcji i wczytajmy ponownie (poprawnie) dane:
daneusa <- read.csv("dane/daneusa.csv")
class(daneusa); str(daneusa)
## [1] "data.frame"
## 'data.frame': 35072 obs. of 29 variables:
## $ UMARSTAT: chr "Never married" "Separated" "Married_live together" "Divorced" ...
## $ UCUREMP : chr "No" "Yes" "No" "No" ...
## $ UCURNINS: chr "Yes" "No" "No" "Yes" ...
## $ USATMED : chr "Very satisfied" "Very satisfied" "Very satisfied" "Little dissatisfied" ...
## $ URELATE : int 2 2 5 4 0 1 0 1 0 0 ...
## $ REGION : chr "Midwest" "Midwest" "Midwest" "Midwest" ...
## $ STATE : chr "WI" "WI" "WI" "WI" ...
## $ HHID : int 55616128 54704000 57874272 54106816 54569152 50199136 55660032 52425472 51796480 51796480 ...
## $ FHOSP : chr "No" "No" "No" "No" ...
## $ FDENT : int 0 2 0 0 2 0 0 1 5 3 ...
## $ FEMER : int 0 0 1 0 0 1 1 5 5 4 ...
## $ FDOCT : int 0 0 0 1 0 1 3 1 0 0 ...
## $ UIMMSTAT: chr "US-born citizen" "US-born citizen" "US-born citizen" "US-born citizen" ...
## $ U_USBORN: chr "Yes" "Yes" "Yes" "Yes" ...
## $ UAGE : int 22 30 33 41 34 39 19 18 24 21 ...
## $ U_FTPT : chr "Full-time" "Full-time" "Part-time" "Part-time" ...
## $ U_WKSLY : num 52 52 52 43 52 39 30 48 52 26 ...
## $ U_HRSLY : int 40 40 30 40 40 45 20 32 40 40 ...
## $ U_USHRS : int 40 40 30 25 40 30 40 40 40 47 ...
## $ HEARNVAL: int 0 31468 24700 60000 55280 41333 105000 0 6000 42000 ...
## $ HOTHVAL : int 0 5950 11340 39002 4200 8177 1000 44400 4800 1272 ...
## $ HRETVAL : int 0 0 0 0 0 0 0 12000 0 0 ...
## $ HSSVAL : int 0 0 4920 0 0 5933 0 20400 0 0 ...
## $ HWSVAL : int 0 31468 24700 60000 55280 41333 105000 0 0 42000 ...
## $ UBRACE : chr "White" "White" "White" "Black" ...
## $ GENDER : chr "Female" "Female" "Male" "Female" ...
## $ UEDUC3 : chr "No HS diploma or GED" "HS diploma or GED, no bachelor's degree" "No HS diploma or GED" "No HS diploma or GED" ...
## $ CEYES : chr "hazel" "blue" "brown" "brown" ...
## $ CHAIR : chr "brown" "black" "brown" "black" ...
Dawniej wszystkie kolumny tekstowe były domyślnie konwertowane do
factors. Aby tego uniknąć trzeba było użyć jawnie opcji
stringsAsFactors = FALSE. Aktualnie jest włączona domyślnie
na FALSE.
daneusa <- read.csv("dane/daneusa.csv",
stringsAsFactors = FALSE)
Inne warianty funkcji read.table() to np.
read.delim() oraz read.delim2() do plików o
stałej szerokości kolumn.
Dane można też importować poprzez “Import Dataset” w oknie środowiska.
readrJest to pakiet z Universum tidyverse (https://www.tidyverse.org/). Na stronie pakietu czytamy,
że “the tidyverse is an opinionated collection of R packages designed
for data science. All packages share an underlying design philosophy,
grammar, and data structures.” Sprawdźmy jak to działa. Ważna informacja
jest taka, że funkcje z rodziny tidyverse działają szybciej
niż funkcje dostępne w default’owo dostępne w pakiecie
utils.
# ?read_csv2
library(readr)
read_csv2(file = "dane/dane_titanic.csv",
n_max = 5) # inaczej niż w przypadku poznanej właśnie funkcji read.csv2()
## ℹ Using "','" as decimal and "'.'" as grouping mark. Use `read_delim()` for more control.
## Rows: 5 Columns: 1
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ";"
## chr (1): passenger_id,pclass,survived,name,sex,age,sibsp,parch,ticket,fare,c...
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
## # A tibble: 5 × 1
## passenger_id,pclass,survived,name,sex,age,sibsp,parch,ticket,fare,cabin,emba…¹
## <chr>
## 1 "1,1,1,\"Allen, Miss. Elisabeth Walton\",1,29,0,0,24160,211.3375,B5,S,\"St Lo…
## 2 "2,1,1,\"Allison, Master. Hudson Trevor\",0,0.9167,1,2,113781,151.55,C22 C26,…
## 3 "3,1,0,\"Allison, Miss. Helen Loraine\",1,2,1,2,113781,151.55,C22 C26,S,\"Mon…
## 4 "4,1,0,\"Allison, Mr. Hudson Joshua Creighton\",0,30,1,2,113781,151.55,C22 C2…
## 5 "5,1,0,\"Allison, Mrs. Hudson J C (Bessie Waldo Daniels)\",1,25,1,2,113781,15…
## # ℹ abbreviated name:
## # ¹`passenger_id,pclass,survived,name,sex,age,sibsp,parch,ticket,fare,cabin,embarked,home.dest`
read_csv(file = "dane/dane_titanic.csv",
n_max = 5) # tu działa
## Rows: 5 Columns: 13
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (4): name, cabin, embarked, home.dest
## dbl (9): passenger_id, pclass, survived, sex, age, sibsp, parch, ticket, fare
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
## # A tibble: 5 × 13
## passenger_id pclass survived name sex age sibsp parch ticket fare cabin
## <dbl> <dbl> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 1 1 1 Alle… 1 29 0 0 24160 211. B5
## 2 2 1 1 Alli… 0 0.917 1 2 113781 152. C22 …
## 3 3 1 0 Alli… 1 2 1 2 113781 152. C22 …
## 4 4 1 0 Alli… 0 30 1 2 113781 152. C22 …
## 5 5 1 0 Alli… 1 25 1 2 113781 152. C22 …
## # ℹ 2 more variables: embarked <chr>, home.dest <chr>
read_delim(file = "dane/dane_titanic.csv",
delim = ",", # -> działa po uzupełnieniu dodatkowego argumentu
n_max = 5)
## Rows: 5 Columns: 13
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (4): name, cabin, embarked, home.dest
## dbl (9): passenger_id, pclass, survived, sex, age, sibsp, parch, ticket, fare
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
## # A tibble: 5 × 13
## passenger_id pclass survived name sex age sibsp parch ticket fare cabin
## <dbl> <dbl> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 1 1 1 Alle… 1 29 0 0 24160 211. B5
## 2 2 1 1 Alli… 0 0.917 1 2 113781 152. C22 …
## 3 3 1 0 Alli… 1 2 1 2 113781 152. C22 …
## 4 4 1 0 Alli… 0 30 1 2 113781 152. C22 …
## 5 5 1 0 Alli… 1 25 1 2 113781 152. C22 …
## # ℹ 2 more variables: embarked <chr>, home.dest <chr>
Data.TableTak jak świat gitarzystów podzielony jest na sięgających po
Fendery bądź GIBSONy, lub tak jak masy
czytających komiksy o (przeważnie amerykańskich) superbohaterach na
fanów DC bądź MARVEL’a, tak świat
R’owców dzieli się na ludzi ze stajni tidyverse i tych
używających Data.Table. Performance
Data.Table jest niesamowity, jeśli chodzi o szybkość,
jednak jest wielu konserwatystów odrzucających to rozwiązanie (sporo
różnic w data wrangling’u)
# install.packages("data.table")
library(data.table)
fread(input = "dane/dane_titanic.csv",
nrows = 5)
## passenger_id pclass survived name
## <int> <int> <int> <char>
## 1: 1 1 1 Allen, Miss. Elisabeth Walton
## 2: 2 1 1 Allison, Master. Hudson Trevor
## 3: 3 1 0 Allison, Miss. Helen Loraine
## 4: 4 1 0 Allison, Mr. Hudson Joshua Creighton
## 5: 5 1 0 Allison, Mrs. Hudson J C (Bessie Waldo Daniels)
## sex age sibsp parch ticket fare cabin embarked
## <int> <num> <int> <int> <int> <num> <char> <char>
## 1: 1 29.0000 0 0 24160 211.3375 B5 S
## 2: 0 0.9167 1 2 113781 151.5500 C22 C26 S
## 3: 1 2.0000 1 2 113781 151.5500 C22 C26 S
## 4: 0 30.0000 1 2 113781 151.5500 C22 C26 S
## 5: 1 25.0000 1 2 113781 151.5500 C22 C26 S
## home.dest
## <char>
## 1: St Louis, MO
## 2: Montreal, PQ / Chesterville, ON
## 3: Montreal, PQ / Chesterville, ON
## 4: Montreal, PQ / Chesterville, ON
## 5: Montreal, PQ / Chesterville, ON
Data.Table vs dplyr| Operacja / Warunek | Zwycięzca Wydajności | Szczegóły |
|---|---|---|
| Bardzo Duże Zbiory Danych |
data.table
|
Osiąga przewagę 3-10x (a czasem więcej), głównie dzięki działaniu przez referencję i braku kopiowania całego zbioru. |
|
Grupowanie i Agregacja ( by
vs. group_by/summarise)
|
data.table
|
Wykorzystuje algorytmy sortowania radix, co daje znaczną przewagę, zwłaszcza przy dużej liczbie grup. |
|
Czytanie Danych ( fread vs. read_csv)
|
data.table
|
Funkcja fread() jest uznawana za najszybszą metodę
wczytywania plików CSV w R.
|
|
Mniejsze Zbiory Danych (< 1 mln wierszy) |
Remis / dplyr
|
Różnice są minimalne lub dplyr może być nieznacznie szybszy
w prostych operacjach ze względu na narzut data.table.
|
https://www.youtube.com/watch?v=SfrjF5YSj0Y
.RDataOgromną zaletą formatu .RData jest fakt, że pozwala
zapisywać w jednym pliku wiele obiektów, także jeśli nie są bazami
danych. Kompresuje wielkość plików, przez co nie zajmują tyle samo
miejsca, co pliki tekstowe bądź obiekty wczytane do R (w pamięci RAM).
Możemy to sprawdzić w naszym systemie operacyjnym, zapisując ten sam
obiekt w kilku formatach (skoro poznaliśmy jak dotąd co najmniej dwie
opcje: .txt oraz .csv).
Do zapisu używamy funkcji save(), zaś do odczytu funkcji
load()
save(mtcars, diamonds, iris, # dla przypomnienia - predefiniowane ramki
file = 'dane/przyklad.RData')
Usuńmy trzy obiekty (mtcars, diamonds,
iris), które potencjalnie mamy w Global
Environment, żeby upewnić się co do prawidłowego działania funkcji
load()
rm(mtcars, diamonds, iris)
I wczytajmy ponownie.
load('dane/przyklad.RData')
Są w środowisku? Spójrzmy w RStudio lub sprawdźmy kodem.
c("mtcars","iris") %in% ls()
## [1] TRUE TRUE
Sporą wadą plików .RData i używania poleceń
save() i load() jest to, że przy wczytywaniu
plików z dysku nadpisują one obiekty o takiej samej nazwie będące już w
środowisku. Przykładowo, jeśli posiadamy już zbiór o nazwie
diamonds, jego miejsce zajmie obiekt o tej samej nazwie,
znajdujący się w pliku .Rdata.
Co więcej, w “internetach”, jak choćby na bardzo wiarygodnym i
użytecznym forum stackoverflow można przeczytać, że pliki
.Rdata mogą ulegać uszkodzeniu. Nie jest to nagminne, ale
warto mieć w pamięci.
.rda.rda to dokładnie ten sam format co .RData—
tylko inna konwencja nazewnictwa. Niektórzy preferują .rda
dla pojedynczych obiektów, a .RData dla zrzutów całej
sesji, ale technicznie to identyczne pliki.
Właściwości techniczne
Format binarny (nieczytelny dla człowieka).
Kompresowany (domyślnie GZip, można zmienić np. na xz dla lepszej kompresji).
Można go przenosić między systemami (Windows, macOS, Linux).
Obsługuje dowolne typy obiektów R – nie tylko dane tabelaryczne.
Nie przechowuje środowiska globalnego jako całości (chyba że
użyjesz save.image()).
save.image(file = "session.RData")
.RdsTo alternatywny dla .RData format plików. Również dobrze
skompresowany, dający dodatkowo możliwość nazywania wczytanych obiektów.
W tym formacie jednak, możemy zapisać tylko jeden plik.
# zapis
saveRDS(diamonds,
file = 'dane/diamonds.rds')
# wczyranie
diamonds <- readRDS('dane/diamonds.rds')
head(diamonds,3)
## # A tibble: 3 × 10
## carat cut color clarity depth table price x y z
## <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
## 1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
## 2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
## 3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
Pakietów do wczytywania Excel’owych plików jest wiele. Nauczmy się
robić to używając pakietu np. readxl.
Instalacja i uruchomienie pakietów.
# install.packages("readxl")
# install.packages("writexl")
library(readxl)
library(writexl)
Obejrzyjmy zbiór poza RStudio.
A następnie wczytajmy dane.
# read_excel(path, sheet = NULL)
titanic1 <- read_excel(
path = "dane/Titanic2.xlsx"
) # bez podania dodatkowych argumentów
## New names:
## • `` -> `...3`
## • `` -> `...4`
head(titanic1, 10)
## # A tibble: 10 × 4
## `Sum of passenger_id` `Column Labels` ...3 ...4
## <chr> <dbl> <dbl> <chr>
## 1 Row Labels 0 1 Grand Total
## 2 0 490200 91475 581675
## 3 1 20437 9703 30140
## 4 2 66779 11766 78545
## 5 3 402984 70006 472990
## 6 1 110284 165436 275720
## 7 1 571 21615 22186
## 8 2 5428 44001 49429
## 9 3 104285 99820 204105
## 10 Grand Total 600484 256911 857395
Chcieliśmy inny sheet i raw data, zatem…
titanic2 <- read_excel(
path = "dane/Titanic2.xlsx",
sheet = 2
)
head(titanic2, 5)
## # A tibble: 5 × 15
## passenger_id pclass survived name sex age sibsp parch ticket fare cabin
## <dbl> <dbl> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <chr> <dbl> <chr>
## 1 1 1 1 Alle… 1 29 0 0 24160 211. B5
## 2 2 1 1 Alli… 0 0.917 1 2 113781 152. C22 …
## 3 3 1 0 Alli… 1 2 1 2 113781 152. C22 …
## 4 4 1 0 Alli… 0 30 1 2 113781 152. C22 …
## 5 5 1 0 Alli… 1 25 1 2 113781 152. C22 …
## # ℹ 4 more variables: embarked <chr>, boat <chr>, body <dbl>, home.dest <chr>
A co jeśli mamy taki plik? Obejrzyjmy go w Excelu.
Wówczas
titanic3 <- read_excel(
path = "dane/Titanic3.xlsx",
sheet = 2, skip = 3, col_names = F
)
## New names:
## • `` -> `...1`
## • `` -> `...2`
## • `` -> `...3`
## • `` -> `...4`
## • `` -> `...5`
## • `` -> `...6`
## • `` -> `...7`
## • `` -> `...8`
## • `` -> `...9`
## • `` -> `...10`
## • `` -> `...11`
## • `` -> `...12`
## • `` -> `...13`
## • `` -> `...14`
## • `` -> `...15`
head(titanic3, 2)
## # A tibble: 2 × 15
## ...1 ...2 ...3 ...4 ...5 ...6 ...7 ...8 ...9 ...10 ...11 ...12 ...13
## <dbl> <dbl> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <chr> <dbl> <chr> <chr> <chr>
## 1 1 1 1 Alle… 1 29 0 0 24160 211. B5 S 2
## 2 2 1 1 Alli… 0 0.917 1 2 1137… 152. C22 … S 11
## # ℹ 2 more variables: ...14 <dbl>, ...15 <chr>
Niestety bez nagłówków kolumn. Czasem gdy cyklicznie otrzymujemy od kogoś zrzuty w Excel’u, teoretycznie o tej samej strukturze, ale wycięte przez przypadek przez użytkownika, możemy nagłówki zaczerpnąć z poprzedniej wersji zbioru.
names(titanic3) <- names(titanic2) # ale tu mieliśmy szczęśliwie skąd pożyczyć
head(titanic3, 3)
## # A tibble: 3 × 15
## passenger_id pclass survived name sex age sibsp parch ticket fare cabin
## <dbl> <dbl> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <chr> <dbl> <chr>
## 1 1 1 1 Alle… 1 29 0 0 24160 211. B5
## 2 2 1 1 Alli… 0 0.917 1 2 113781 152. C22 …
## 3 3 1 0 Alli… 1 2 1 2 113781 152. C22 …
## # ℹ 4 more variables: embarked <chr>, boat <chr>, body <dbl>, home.dest <chr>
Należy pamiętać jak wygląda praca w programie SPSS. Mamy tam dwa
okna, pierwszy widok umożliwia podejrzenie danych, drugi pozwala
przyjrzeć się kategoriom, jeśli zmienna ma taki charakter
(factor w R)
Instalacja i uruchomienie pakietów.
# install.packages("haven")
require(haven)
## Loading required package: haven
I wczytanie danych.
spss_df <- read_sav(file = "dane/IBM SPSS Sample Files/accidents.sav")
# jak podejrzeć nazwy kategorii?
# attr(spss_df$gender, "label")
attr(spss_df$gender, "labels")
## Male Female
## 0 1
class(spss_df)
## [1] "tbl_df" "tbl" "data.frame"
typeof(spss_df)
## [1] "list"
# so...
is.data.frame(spss_df) # how?
## [1] TRUE
summary(spss_df)
## agecat gender accid pop
## Min. :1.00 Min. :0.0 Min. :54123 Min. :187791
## 1st Qu.:1.25 1st Qu.:0.0 1st Qu.:57334 1st Qu.:196416
## Median :2.00 Median :0.5 Median :60967 Median :199633
## Mean :2.00 Mean :0.5 Mean :60801 Mean :199035
## 3rd Qu.:2.75 3rd Qu.:1.0 3rd Qu.:64610 3rd Qu.:202586
## Max. :3.00 Max. :1.0 Max. :66804 Max. :208239
Inny sposób (z użyciem innego pakietu), który być może jest wygodniejszy do importu danych ankietowych (głównie kategorialne zmienne)
# install.packages("foreign")
library(foreign)
spss_df2 <- read.spss(file = "dane/IBM SPSS Sample Files/accidents.sav",
use.value.labels = TRUE # ten argument pozwala korzystać z etykiet
)
class(spss_df2)
## [1] "list"
typeof(spss_df2)
## [1] "list"
is.data.frame(spss_df2)
## [1] FALSE
summary(spss_df2)
## Length Class Mode
## agecat 6 factor numeric
## gender 6 factor numeric
## accid 6 -none- numeric
## pop 6 -none- numeric
Znając link do strony, gdzie ktoś trzyma interesujący nas zasób bazodanowy, możemy posłużyć się funkcjami dostępnymi w R, żeby taką ramkę ściągnąć i zacząć “obrabiać” bezpośrednio w środowisku R
(investment_annual_summary <- readr::read_csv("https://assets.datacamp.com/production/repositories/5756/datasets/d0251f26117bbcf0ea96ac276555b9003f4f7372/investment_annual_summary.csv", show_col_types = FALSE))
## # A tibble: 42 × 3
## fiscal_year region dollars_in_millions
## <dbl> <chr> <dbl>
## 1 2012 East Asia and the Pacific 2548
## 2 2012 Europe and Central Asia 2915
## 3 2012 Latin America and the Caribbean 3680
## 4 2012 Middle East and North Africa 2210
## 5 2012 South Asia 1312
## 6 2012 Sub-Saharan Africa 2733
## 7 2013 East Asia and the Pacific 2873
## 8 2013 Europe and Central Asia 3261
## 9 2013 Latin America and the Caribbean 4822
## 10 2013 Middle East and North Africa 2038
## # ℹ 32 more rows
# przykład z internetowego tutorial'u Dr Eugene O'Loughlin'a
url = "https://raw.githubusercontent.com/eoloughlin/How-To-R/master/24_Data_File.csv"
priceData <- read.csv(url)
head(priceData, 6) # Zobacz sześć pierwszych wierszy
## Oil Gold
## 1 50 1267
## 2 46 1238
## 3 54 1157
## 4 55 1192
## 5 55 1234
## 6 52 1231
tail(priceData, 6) # Zobacz sześć ostatnich wierszy
## Oil Gold
## 7 53 1267
## 8 51 1246
## 9 47 1260
## 10 49 1237
## 11 51 1283
## 12 55 1314
names(priceData) # sprawdź nazwy kolumn
## [1] "Oil" "Gold"
Przykład połączenia się z portalem https://clinicaltrials.gov/ . Jest to publiczne
źródło informacji o badaniach klinicznych nad lekami (po zarejestrowaniu
się). Korzystając z pakietu RPostgreSQL możemy kwerendować
bazę portalu używając składni SQL (w implementacji
PostgreSQL)
###### Packages ######
# install.packages("Rtools")
# install.packages("RPostgreSQL")
# install.packages("DBI")
library(RPostgreSQL)
###### Credentials ######
# https://aact.ctti-clinicaltrials.org/r
Hostname = "aact-db.ctti-clinicaltrials.org"
Port = 5432
Database_name = "aact"
User_name = "LooserName"
Password = "password"
###### Connection ######
drv <- dbDriver('PostgreSQL')
class(drv)
con <- dbConnect(drv,
dbname = Database_name,
host="aact-db.ctti-clinicaltrials.org",
port= Port ,
user=(User_name),
password=Password)
class(con)
###### Info ######
# https://aact.ctti-clinicaltrials.org/schema
# https://aact.ctti-clinicaltrials.org/data_dictionary
###### Query ######
studyTypes <- dbGetQuery(con,
"SELECT DISTINCT study_type FROM studies")
suties <- dbGetQuery(con,
"SELECT * FROM studies LIMIT 20")
############### libraries ###############
library(DBI)
library(odbc)
library(data.table)
############### Nokia ###############
con <- dbConnect(odbc(),
Driver = "SQL Server",
Server = "nazwa_serwera",
UID = "Uzytkownik_readonly",
PWD = rstudioapi::askForPassword("Uzytkownik_readonly@2"))
############### queries ###############
query <- c("SELECT Top 10 * FROM CT.dbo.facilities f")
studies <- data.table(
dbGetQuery(con, query)
)
###
query <- c(
"SELECT f.nct_id AS project_id, f.country, COUNT(f.id) AS sites_count
FROM CT.dbo.facilities f
JOIN (SELECT DISTINCT st.nct_id
FROM CT.dbo.studies st
LEFT JOIN CT.dbo.sponsors sp ON sp.nct_id = st.nct_id
LEFT JOIN CT.dbo.calculated_values cv ON st.nct_id = cv.nct_id
LEFT JOIN CT.dbo.conditions cn ON st.nct_id = cn.nct_id
LEFT JOIN CT.dbo.eligibilities e ON st.nct_id = e.nct_id
WHERE
st.start_date > '2010-01-01' AND st.study_type = 'Interventional'
AND sp.agency_class = 'INDUSTRY' AND sp.lead_or_collaborator = 'lead'
) s ON f.nct_id = s.nct_id
WHERE
f.country IS NOT NULL
AND f.country IN ('Poland', 'Austria','Belgium','Bosnia','Denmark','Estonia','Finland','Latvia',
'Lithuania','Macedonia','Netherlands','Norway')
GROUP BY
f.nct_id, f.country;"
)
SiteCount <- data.table(
dbGetQuery(con,
query)
)
Wyobraźmy sobie sytuację, że nie mamy licencji do SPSS’a, a znalezione pliki są zapisane w formacie .sav. Jeśli chcemy skorzystać z tym danych mimo wszystko, to możemy je w R skonwertować do każdego innego formatu. Poniżej zajawka jak to zrobić stojąc przed koniecznością skonwertowania wielu plików.
# install.packages("tidyverse")
# install.packages("fs")
library(tidyverse)
library(fs)
# wczytywanie wielu plików na raz (np. SPSS'owych)
lista_plikow <- dir("dane/IBM SPSS Sample Files/")
dane_spss_mult <- list()
library(haven)
for (i in seq_along(lista_plikow)) { # == 1:length(lista_plikow)
dane_spss_mult[[i]] <- read_sav(
file = paste0("dane/IBM SPSS Sample Files/",
lista_plikow[[i]]
)
)
}
library(tidyverse)
dane_spss_mult <- set_names(x = dane_spss_mult,
nm = lista_plikow)
# sprawdzenie losowego zbioru
head(dane_spss_mult$bankloan.sav, 4)
# potencjalnie mogę sobie wyciąg z listy zbiory, które mnie interesują i przypisywać do obiektów
accidents.sav <- dane_spss_mult$accidents.sav
class(accidents.sav)
adl.sav <- dane_spss_mult$adl.sav
advert.sav <- dane_spss_mult$advert.sav
bankloan.sav <- dane_spss_mult$bankloan.sav
behavior.sav <- dane_spss_mult$behavior.sav
car_sales.sav <- dane_spss_mult$car_sales.sav
contacts.sav <- dane_spss_mult$contacts.sav
customer_dbase.sav <- dane_spss_mult$customer_dbase.sav
demo.sav <- dane_spss_mult$demo.sav
dietstudy.sav <- dane_spss_mult$dietstudy.sav
dmdata3.sav <- dane_spss_mult$dmdata3.sav
ozone.sav <- dane_spss_mult$ozone.sav
poll_cs_sample.sav <- dane_spss_mult$poll_cs_sample.sav
satisf.sav <- dane_spss_mult$satisf.sav
telco.sav <- dane_spss_mult$telco.sav
workprog.sav <- dane_spss_mult$workprog.sav
getwd() # sprawdzenie ścieżki
# zapisywanie wielu plików na raz (np. do .csv)
data_names <- names(dane_spss_mult)
for(i in 1:length(data_names)) {
write.csv2(x = get(data_names[i]),
file = paste0("/dane/IBM SPSS Sample Files/",
data_names[i],
".csv"),
row.names = FALSE)
}
dir() # pliki i foldery w ścieżce roboczej
list.files() # lista plików i folderów
list.dirs() # lista potencjalnych ścieżek dostępu
dir.create('~/Statystyka1_R/materialy/Zaj_3/dane/Dane2') # stworzenie folderu
dir.exists('dane') # sprawdzenie czy folder istnieje
file.copy(from = './script.R',
to = 'Zaj_3') # skopiowanie pliku
file.create('dane/script_new.R') # stworzenie pliku
file.edit('dane/script_new.R') # edycja pliku
file.exists('dane/script_new.R') # sprawdzanie czy plik istnieje
file.remove('dane/script.R') # skasowanie pliku
file.rename('dane/script.R', 'dane/script2.R') # zmiana nazwy pliku
file.size('dane/script.R') # wielkość pliku
file.info('dane/script.R') # info o pliku
Przy zarządzaniu plikami, warto jeszcze zdawać sobie sprawę, że
istnieje możliwość zdalnego pakowania i rozpakowywania plików, przez
polecenie unzip
unzip(zipfile = '~/Statystyka1_R/materialy/Zaj_3/dane/ibm_spss_sample_files_0.zip',
exdir = '~/Statystyka1_R/materialy/Zaj_3/dane/Dane2')
Porównanie szybkość trzech funkcji do wczytywania plików z danymi
# install.packages("microbenchmark")
library(microbenchmark)
compare <- microbenchmark(read.csv2("dane/diamonds2.csv"),
readRDS("dane/diamonds2.rds"),
load("dane/diamonds2.rda"),
times = 10)
compare
## Unit: milliseconds
## expr min lq mean median
## read.csv2("dane/diamonds2.csv") 123.067801 137.034101 182.25557 172.985051
## readRDS("dane/diamonds2.rds") 8.019701 8.591401 14.60872 9.678601
## load("dane/diamonds2.rda") 8.498001 9.513301 14.06737 9.862251
## uq max neval
## 231.1824 258.1293 10
## 16.2806 42.2696 10
## 11.9462 44.0658 10
library(knitr)
kable(compare)
| expr | time |
|---|---|
| readRDS(“dane/diamonds2.rds”) | 42269601 |
| load(“dane/diamonds2.rda”) | 44065801 |
| read.csv2(“dane/diamonds2.csv”) | 223434901 |
| read.csv2(“dane/diamonds2.csv”) | 180148601 |
| read.csv2(“dane/diamonds2.csv”) | 231182401 |
| read.csv2(“dane/diamonds2.csv”) | 258129301 |
| readRDS(“dane/diamonds2.rds”) | 8591401 |
| load(“dane/diamonds2.rda”) | 9513301 |
| load(“dane/diamonds2.rda”) | 9742401 |
| readRDS(“dane/diamonds2.rds”) | 9296701 |
| read.csv2(“dane/diamonds2.csv”) | 137034101 |
| readRDS(“dane/diamonds2.rds”) | 18685401 |
| readRDS(“dane/diamonds2.rds”) | 9457302 |
| read.csv2(“dane/diamonds2.csv”) | 231940701 |
| read.csv2(“dane/diamonds2.csv”) | 165821501 |
| read.csv2(“dane/diamonds2.csv”) | 143155001 |
| load(“dane/diamonds2.rda”) | 11946200 |
| load(“dane/diamonds2.rda”) | 10644201 |
| readRDS(“dane/diamonds2.rds”) | 8220901 |
| load(“dane/diamonds2.rda”) | 8784901 |
| readRDS(“dane/diamonds2.rds”) | 16280601 |
| read.csv2(“dane/diamonds2.csv”) | 123067801 |
| read.csv2(“dane/diamonds2.csv”) | 128641402 |
| readRDS(“dane/diamonds2.rds”) | 15365701 |
| readRDS(“dane/diamonds2.rds”) | 8019701 |
| readRDS(“dane/diamonds2.rds”) | 9899901 |
| load(“dane/diamonds2.rda”) | 8498001 |
| load(“dane/diamonds2.rda”) | 17754401 |
| load(“dane/diamonds2.rda”) | 9911402 |
| load(“dane/diamonds2.rda”) | 9813101 |
# ciekawostka
df <- data.frame(col1 = seq(1,10000, by = 1),
col2 = rep(x = 1:1000, 10),
col3 = rnorm(10000))
m <- as.matrix(df)
microbenchmark(df[,1], m[,1], times = 100)
## Unit: microseconds
## expr min lq mean median uq max neval
## df[, 1] 3.801 4.4515 8.69795 6.0510 10.7005 66.900 100
## m[, 1] 13.300 16.0010 26.54312 19.1005 32.7010 88.701 100
microbenchmark(df[1,], m[1,], times = 100)
## Unit: nanoseconds
## expr min lq mean median uq max neval
## df[1, ] 21200 24701 30979.90 28901.5 32151 156100 100
## m[1, ] 400 602 1123.06 800.0 1000 14302 100
# install.packages("profvis")
library(profvis)
profvis({
#create dataset
data <- data.frame(y=c(6, 7, 7, 9, 12, 13, 13, 15, 16, 19, 22, 23, 23, 25, 26),
x=c(1, 2, 2, 3, 4, 4, 5, 6, 6, 8, 9, 9, 11, 12, 12))
# Tworzy ramkę danych data z dwiema kolumnami:
# y (wartości zmiennej zależnej)
# x (wartości zmiennej niezależnej)
model <- lm(y~x, data=data)
summary(model)
library(ggplot2)
ggplot(data,aes(x, y)) +
geom_point() + # Wykres punktowy geom_point()
geom_smooth(method='lm') # wraz z dopasowaną linią regresji
}) # koniec Profilowania
Cały blok kodu jest profilowany za pomocą funkcji
profvis(). Profilowanie pozwala analizować, ile czasu
zajmują poszczególne etapy wykonywania kodu (np. tworzenie danych,
dopasowanie modelu, generowanie wykresu).
Innymi słowy kod tworzy prosty model regresji liniowej, wizualizuje
go za pomocą wykresu punktowego z linią regresji, a następnie funkcja
profvis() z pakietu {profvis} analizuje jego wydajność.
Sprawdzanie zasobów własnej maszyny w konsoli
R
# install.packages("benchmarkme")
library(benchmarkme)
get_cpu()
## $vendor_id
## [1] "GenuineIntel"
##
## $model_name
## [1] "11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz"
##
## $no_of_cores
## [1] 8
# install.packages("parallel")
library(parallel)
detectCores() # == get_cpu()$no_of_cores
## [1] 8
Źródła i inspiracje pomocne w przygotowaniu niniejszej prezentacji:
Materiały z warsztatów Data Science w zastosowaniach biznesowych - Warsztaty z wykorzystaniem programu R Uniwersytet Warszawski, Wydział Nauk Ekonomicznych
DataCamp.com Introduction to R
DataCamp.com Writing Efficient R Code
Eugene O’Loughlin tutorial
Materiały dr Bartosza Maćkiewicza:
Biecek, Przemysław, “Przewodnik po pakiecie R” http://www.biecek.pl/R/ https://cran.r-project.org/doc/contrib/Biecek-R-basics.pdf
Gągolewski, Marek, “Programowanie w języku R”, “Deep R Programming”, etc. https://deepr.gagolewski.com/index.html
Crawley, Michael J. The R book. John Wiley & Sons, 2012 https://onlinelibrary.wiley.com/doi/book/10.1002/9781118448908
Kabacoff, Robert. R in action: data analysis and graphics with R. Manning Publications Co., 2015 https://www.cs.uni.edu/~jacobson/4772/week11/R_in_Action.pdf
Fox, John, Michael Friendly, and Sanford Weisberg. “Hypothesis tests for multivariate linear models using the car package.” R J 5.1 (2013) https://www.researchgate.net/publication/285736465_Hypothesis_Tests_for_Multivariate_Linear_Models_Using_the_car_Package
Hothorn, Torsten, et al. “Package ‘multcomp’.” Simultaneous inference in general parametric models. Project for Statistical Computing, Vienna, Austria (2016) https://cran.r-project.org/web/packages/multcomp/vignettes/generalsiminf.pdf
claude.ai
chatgpt.com