Kodas
getwd()Įprastai didesnės apimties duomenys laikomi įvairaus formatų failuose, kaip pvz. .txt, .csv, .dat, .xlsx, .JSON ir taip toliau. Bendrai tariant, failų formatus galima klasifikuoti į tekstinius ir binarinius. Šios kategorijos turi skirtingas duomenų saugojimo įpatybes, todėl reikalingi skirtingi būdai kaip tokius failus nuskaityti ar išsaugoti tokiu formatu.
Pagrindinis skirtumas tarp tekstinių ir binarinių failų yra tas, kad binariniai failai neturi jokių vidinių apribojimų (gali būti bet kokia baitų seka) ir jie turi būti atidaromi atitinkama programa, žinančia failo formatą (pvz. „Adobe Photoshop“, „SumatraPDF“ ir kt.). Pagal susitarimą kiekvieno tekstinio failo turinys atitinka tam tikras taisykles ir gali būti redaguojamas bet kuria teksto redagavimo programa.
Norint tinkamai dirbti su duomenimis reikia mokėti apdoroti skirtingų formatų failus, todėl šis skyrius yra išskaidytas į tekstinių ir binarinių failų nuskaitymą ir įrašymą.
Prieš pradedant darbą su R, pravartu nustatyti, iš kokio aplanko bus nuskaitomi ir įrašomi failai. Įsijungus naują R sesiją, pagal nutylėjimą darbinis katalogas yra vartotojo namų aplankas. Norint patikrinti, kuri kompiuterio direktorija yra darbinė, naudojama funkcija getwd()
getwd()#> [1] "C:/Users/DonatasSl/Desktop"
Jei norite, kad R failų ieškotų kitame aplanke – naudojama funkcija setwd(), kurios vienintelis argumentas yra absoliutus arba santykinis kelias:
setwd(dir = "C:/Users/DonatasSl/Desktop/R konspektas")Svarbu žinoti, jog įprastai kelias iki aplanko ar failo nurodomas su atgaliniu pasviruoju brūkšniu \, tačiau R kalboje tai yra specialus simbolis (escape character), kūrį reikia ištraukti naudojant tokį patį simbolį. Tokiu atveju, nurodomas kelias atrodytų taip:
setwd(dir = "C:\\Users\\DonatasSl\\Desktop\\R konspektas")Yra ir kitas galimas simbolis nurodant kelią - priekinis pasvirasis brūkšnys /. Tokiu atveju, nurodomas kelias atrodytų taip:
setwd(dir = "C:/Users/DonatasSl/Desktop/R konspektas")Žinoma, norint nustatyti tam tikrą katalogą, pirma jis turi būti sukurtas.
Tekstinių failų nuskaitymui R turi keletą procedūrų. Aptarsime skirtingus nuskaitomų duomenų atvejus.
Vieno vektoriaus elementų nuskaitymui naudojama funkcija scan(). Ši funkcija vektoriaus elementus nuskaito eilutėmis.
| Argumentas | Reikšmė |
|---|---|
file |
failo vardas arba kelias iki failo, nurodytas kabutėse |
what |
vektoriaus tipas: numeric(), character() ir t.t |
sep |
vektoriaus elementus skiriantis simbolis, pagal nutylėjimą tarpas |
dec |
dešimtainio kablelio simbolis, pagal nutylėjimą - taškas |
skip |
pirmųjų nenuskaitomų failo eilučių skaičius |
nlines |
nuskaitomų failo eilučių skaičius |
n |
maksimalus vektoriaus elementų skaičius |
Jei argumento file reikšmė nenurodoma, tai vektoriaus reikšmės bus įvedamos iš klaviatūros.
Atidarysime testinį failą test_numeric.dat, kuris sudarytas iš skaitinių reikšmių.
x <- scan(file = "data/test_numeric.dat")
x
#> [1] 3.141593 3.141600 3.140000 2.718282 2.718300 2.720000Šiuo atveju nereikėjo nurodyti, kokio tipo reikšmės bus nuskaitomos, nes pagal nutylėjimą duomenys nuskaitomi kaip double() tipo. Tačiau jeigu vektoriaus elementai yra simboliai, reikia nurodyti argumentą what = character(). Pavyzdžiui, nuskaitomas tekstinių duomenų failas test_character.dat.
Ši funkcija naudinga tuo, kad ji leidžia nuskaityti duomenų failus tiesiai iš interneto. Tokiu atveju funkcijos parametrui file reikia nurodyti pilną failo adresą.
Visai teksto eilutei nuskaityti kaip vieną elementą naudojama specialiai tam skirta funkcija readLines(). Argumentas n nurodo nuskaitomų eilučių skaičių.
adresas <- "https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data"
x <- readLines(adresas, n = 4)
x
#> [1] "5.1,3.5,1.4,0.2,Iris-setosa" "4.9,3.0,1.4,0.2,Iris-setosa"
#> [3] "4.7,3.2,1.3,0.2,Iris-setosa" "4.6,3.1,1.5,0.2,Iris-setosa"Duomenų lentelės iš failo nuskaitymui naudojama funkcija read.table().
| Argumentas | Reikšmė |
|---|---|
file |
failo vardas arba kelias iki failo, nurodytas kabutėse |
header |
TRUE nurodo, kad pirmoje eilutėje surašyti kintamųjų pavadinimai |
sep |
stulpelius skiriantis simbolis, pagal nutylėjimą tarpas |
dec |
dešimtainio kablelio simbolis, pagal nutylėjimą - taškas |
skip |
pirmųjų nenuskaitomų failo eilučių skaičius |
nrows |
nuskaitomų failo eilučių skaičius |
row.names |
eilučių vardų vektorius, jų stulpelio numeris arba pavadinimas |
col.names |
stulpelių pavadinimų vektorius |
na.strings |
praleistos reikšmės simbolis, pagal nutylėjimą NA
|
as.is |
jei TRUE, kategoriniai kintamieji nuskaitomi kaip faktoriai |
Pavyzdžiui, nuskaitomas tas pats simbolių vektorius, kurio reikšmės duomenų faile yra surašytos stulpeliu.
df <- read.table(file = "data/test_character.dat")
df
#> V1
#> 1 Lorem
#> 2 ipsum
#> 3 dolor
#> 4 sit
#> 5 ametNenurodžius stulpelio pavadinimo, jis sudaromas automatiškai.
Kaip ir funkcijai scan(), čia galima nurodyti, kad duomenų failas yra internete.
df <- read.table(file = adresas,
sep = ",",
nrows = 4,
col.names = c("Sepal.Length","Sepal.Width","Petal.Length","Petal.Width","Species")
)
df
#> Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1 5.1 3.5 1.4 0.2 Iris-setosa
#> 2 4.9 3.0 1.4 0.2 Iris-setosa
#> 3 4.7 3.2 1.3 0.2 Iris-setosa
#> 4 4.6 3.1 1.5 0.2 Iris-setosaKad duomenis būtų galima nesunkiai perkelti iš vienos programos į kitą, jie į failus rašomi tam tikru standartiniu formatu, kurį daugelis programų žino kaip nuskaityti. Vienas iš populiariausių tekstinio duomenų failo formatas yra taip vadinamas comma separated values arba sutrumpintai .csv. Jis skirtas lentelės pavidalo duomenims užrašyti, kur stulpeliuose yra kintamieji, o eilutėse yra stebiniai.
Funkcija read.csv() naudojama nuskaityti failams, kuriuose stulpeliai vienas nuo kito atskirti kableliu, o trupmeninė skaičiaus dalis skiriama tašku. Nuskaitysime, duomenų rinkinų adult.csv.
df <- read.csv(file = "data/adult.csv", nrows = 5)
df
#> age workclass fnlwgt education education.num marital.status
#> 1 90 ? 77053 HS-grad 9 Widowed
#> 2 82 Private 132870 HS-grad 9 Widowed
#> 3 66 ? 186061 Some-college 10 Widowed
#> 4 54 Private 140359 7th-8th 4 Divorced
#> 5 41 Private 264663 Some-college 10 Separated
#> occupation relationship race sex capital.gain capital.loss
#> 1 ? Not-in-family White Female 0 4356
#> 2 Exec-managerial Not-in-family White Female 0 4356
#> 3 ? Unmarried Black Female 0 4356
#> 4 Machine-op-inspct Unmarried White Female 0 3900
#> 5 Prof-specialty Own-child White Female 0 3900
#> hours.per.week native.country income
#> 1 40 United-States <=50K
#> 2 18 United-States <=50K
#> 3 40 United-States <=50K
#> 4 40 United-States <=50K
#> 5 40 United-States <=50KJei stulpeliai vienas nuo kito atskiriami kabliataškiu, tai trupmeninė skaičiaus dalis skiriama mums įprastu kableliu. Tokio formatuo duomenų failui nuskaityti naudojama funkcija read.csv2().
Aišku, .csv formato failą galima nuskaityti ir naudojant funkciją read.table(), tačiau šiuo atveju nuskaitymo komanda yra paprastesnė. Jei stulpeliai faile atskiriami tabuliacijos ženklu „, tada tokiems duomenims nuskaityti gali būti taikoma funkcija read.delim() arba read.delim2().
Iš tikro visos šios išvardytos funkcijos viduje naudoją vieną ir ta pačią funkciją read.table(), tik su iš anksto nustatytais šios funkcijos argumentais.
Jei duomenys sudėtingos struktūros, kaip pavyzdžiui sąrašai, sudėtinga duomenų lentelė su atributais, R statistinių procedūrų rezultatai, saugoti juos tekstinio failo formatu yra nepatogu. Dingtų atributai, faktorių lygiai ar net tikslumas. Tokiems atvejams R turi binarinį saugojimo formatą su išplėtimu .Rdata.
Tokio formato failai importuojami naudojant funkciją load(). Nuskaitysime duomenų rinkinį woman.Rdata. Nuskaitymo rezultato nereikia priskirti jokiam objektui - importuotas duomenų rinkinys po nuskaitymo iškart matomas prie R sesijos objektų sąrašo.
load(file = "data/woman.Rdata")Kadangi binariai failai neturi vienos bendros struktūros, skirtingo formatų failams reikalingos specifinės funkcijos. Pavyzdžiui, tam pačiam .xlsx formato duomenims nuskaityti, reikalingos funkcijos iš kitų R paketų.
Šio formato failams skaityti yra sukurtas ne vienas paketas. Kuo jie visi skiriasi? Vieni naudojami tik failų nuskaitymui, kiti - ir nuskaitymui, ir įrašymui. Keletas iš jų reikalauja įdiegtos Java JDK, kiti turi mažiau priklausomybių nuo išorinių programų.
| Paketas | Kada verta rinktis? |
|---|---|
readxl |
kasdieninėje veikloje tik greitam failų nuskaitymui |
openxlsx2 |
didelės apimties failams nuskaityti ir įrašyti (> 100 tūkst. eilučių) |
xlsx |
galima nuskaityti ir įrašyti failus, reikalinga Java JDK ir rJava
|
tidyxl |
neįprastai suformatuotiems duomenims nuskaityti |
XLConnect |
niekada nenaudoti |
Jeigu dirbant su duomenimis reikalingas .xlsx formato duomenų nuskaitymas, 99% atvejų tinka readxl paketo funkcijos. Jeigu reikia duomenų lenteles saugoti šiuo formatu - naudoti openxlsx2 paketą.
Pavyzdžiui, nuskaitysime duomenų rinkinį Titanic.xlsx naudojant funkciją read_xlsx() iš paketo readxl.
# instaliuojamas paketas
install.packages("readxl")# įsikeliamas paketas
library(readxl)
df <- read_xlsx(path = "data/Titanic.xlsx", n_max = 5)
df
#> # A tibble: 5 × 12
#> PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin
#> <dbl> <dbl> <dbl> <chr> <chr> <dbl> <dbl> <dbl> <chr> <dbl> <chr>
#> 1 1 0 3 Braund… male 22 1 0 A/5 2… 7.25 <NA>
#> 2 2 1 1 Cuming… fema… 38 1 0 PC 17… 71.3 C85
#> 3 3 1 3 Heikki… fema… 26 0 0 STON/… 7.92 <NA>
#> 4 4 1 1 Futrel… fema… 35 1 0 113803 53.1 C123
#> 5 5 0 3 Allen,… male 35 0 0 373450 8.05 <NA>
#> # ℹ 1 more variable: Embarked <chr>Svarbu paminėti, jog readxl paketas nuskaito duomenis į R sesiją ne kaip data.frame klasės objektą, o kaip tibble lentelę. Tai alternatyvi klasė duomenų lentelėms. Šiame skyriuje daugiau apie tai nebus aptarta.
Skirtingų paketų nuskaitymo greitį galima palyginti tarpusavyje. Šiame pavyzdyje nuskaitysime didelės apimties .xlsx formato failą 5 kartus.
failas <- "data/100mb.xlsx"
library(microbenchmark) # palyginimui naudojamas paketas
library(xlsx)
library(readxl)
library(openxlsx2)
library(tidyxl)
read_xlsx_java <- function() { xlsx::read.xlsx(failas, sheetIndex = 1) }
read_xlsx_readxl <- function() { readxl::read_xlsx(failas, sheet = 1) }
read_xlsx_ox2 <- function() { openxlsx2::read_xlsx(failas, sheet = 1) }
read_xlsx_tidyxl <- function() { tidyxl::xlsx_cells(failas, sheets = 1) }
set.seed(20250529)
rezultatas <- microbenchmark(
# xlsx = read_xlsx_java(),
readxl = read_xlsx_readxl(),
openxlsx2 = read_xlsx_ox2(),
tidyxl = read_xlsx_tidyxl(),
times = 5
)
print(rezultatas, signif = 3)Išvada: readxl paketo funkcija nuskaitymui veikia greičiausiai iš šių trijų variantų. Šiame eksperimente readxl paketo funkcija veikė greičiau už openxlsx2 du kartus, o už tidyxl - beveik net 3 kartus.
Vektoriaus ar matricos reikšmės į tekstinį failą įrašomos naudojant funkciją write(). Duomenys į failą įrašomi pagal eilutes.
| Argumentas | Reikšmė |
|---|---|
x |
R objektas: vektorius arba matrica |
file |
kuriamo duomenų failo vardas arba kelias iki failo |
sep |
simbolis, kuriuo faile atskiriamos vektoriaus reikšmės |
ncolumns |
vektoriaus elementų skaičius vienoje failo eilutėje |
append |
loginis kintamasis; jeigu TRUE - reikšmės įrašomos į jau esantį failą |
Kintamojo reikšmės surašomos į tekstinį failą, bet failo išplėtimas nebūtinai turi būti .txt. Pagal nutylėjimą, skaitinio vektoriaus reikšmės faile surašomos po 5 reikšmes į eilutę, o simbolinio - po vieną elementą į eilutę.
Pavyzdžiui, įrašysime skaitinį vektorių į tekstinį failą.
Kaip žinoti, kokiame kataloge išsaugotas failas numeric.vec?
Tą patį vektorių išsaugome į failą, atskiriant reikšmes po vieną per eilutę.
Matricas taip pat galima įrašyti į failą, nes jos suprantamos kaip vektoriaus elementai išdėstyti stulpeliais arba eilutėmis. Kadangi matricos elementai nuskaitomi pagal stulpelius, o į failą įrašomi eilutėmis, tam, kad faile matrica turėtų tokius pat išmatavimus ir tinkamai būtų atvaizduota, ją reikia transponuoti.
Naudodami funkciją write(), užrašykite komandą, kuri matricos mat elementus į failą surašytų viename stulpelyje.
Naudodami funkciją write(), užrašykite komandą, kuri tekstinio vektoriaus c("Pirmas sakinys.", "Antras sakinys.", "Trečias sakinys.", "Jau pabaiga.") elementus į konsolę užrašytų dviem stulpeliais.
Papildykite antros užduoties rezultatą taip, kad elementai būtų išrašomi be tarpų.
Duomenų lentelės į tekstinį failą rašomos naudojant funkciją write.table().
| Argumentas | Reikšmė |
|---|---|
x |
duomenų lentelė |
file |
kuriamo duomenų failo vardas arba kelias iki failo |
sep |
simbolis, kuriuo faile atskiriamos vektoriaus reikšmės |
dec |
dešimtainis kablelio simbolis, pagal nutylėjimą - taškas |
row.names |
jei TRUE, tai lentelė įrašoma su eilučių pavadinimais |
col.names |
jei TRUE, tai lentelė įrašoma su stulpelių pavadinimais |
append |
jei TRUE, vektoriaus reikšmės įrašomos į jau egzistuojantį failą |
quote |
jei TRUE, tekstiniai kintamieji ir faktoriai rašomi kabutėse |
Vietoje loginių reikšmių, parametrams row.names ir col.names galima priskirti vardų vektorių.
Sudarysime duomenų lentelę df, kurios stulpeliuose yra trys skirtingo tipo vektoriai. Ją išsaugosime į failą duomenys.dat.
x <- c(22.1, 37.5, 68.3, 15)
y <- c(FALSE, TRUE, TRUE, FALSE)
z <- c("sutinku", "nesutinku", "visiškai sutinku", "nesutinku")
df <- data.frame(x, y, z)
write.table(df, file = "data_exp/duomenys.dat")Kategorinė reikšmė gali būti keli žodžiai, pvz. „Jonas Petraitis“. Jei stulpelius failuose skiriame tarpu, toks įrašas išsiskaidytų vieną reikšmę į kelis pavienius stulpelius, todėl R visus kelių žodžių tekstus automatiškai įrašo kabutėse. Naudodami kitą skirtuką (tabuliatorių „, kabliataškį ir pan.) kabučių nebereikia, t.y. quote = FALSE.
Atskiras stulpelius sukuriamas eilučių pavadinimams įrašant į failą. Tais atvejais, eilučių pavadinimai sutampa su numeriais, į failą jų galima ir nerašyti.
write.table(df, file = "data_exp/duomenys.dat", row.names = FALSE)Analogiškai nuskaitymui, funkcijos write.csv() ir write.csv2() skirtos duomenų lentelių įrašymui .csv formatu. Šios funkcijos remiasi write.table() funkcija su iš anksto nustatytais sep ir dec parametrais.
Naudojame write.csv(), kai stulpeliai atskiriami vienas nuo kito kableliu, o su write.csv2() stulpeliai atskiriami kabliataškiu, tai kableliu atskiriama trupmeninė skaičiaus dalis.
write.csv(x = df, file = "data_exp/csv_duomenys.csv")
write.csv2(x = df, file = "data_exp/csv2_duomenys.csv")Duomenų lentelėje iris yra duomenys apie kelių rūšių augalų žiedų matavimus. Naudodami funkciją write.table(), įrašykite šiuos matavimus į tekstinį failą: stulpeliai faile atskiriame tabuliacijos ženklu, kategoriniai kintamieji rašomi be kabučių, eilučių numerių nėra.
Naudodami funkciją write.table(), duomenų lentelę cars įrašykite į tekstinį failą su lietuviškais stulpelių pavadinimais.
.csv formatu įrašykite duomenų lentelę iris. Trupmeninė skaičiaus dalis turi būti skiriama kableliu.
# 1.
write.table(x = iris, file = "data_exp/irisas.txt", sep = "\t", quote = F, row.names = F)
# 2.
write.table(cars, "data_exp/masinos.txt", col.names = c("greitis", "atstumas"))
# 3.
write.csv2(iris, "data_exp/irisas.csv")Binariniu formatu patogu saugoti objektus sukurtus R aplinkoje. R duomenų failai turi .RData išplėtimą. Duomenis binariniu formatu įrašome su funkcija save().
Pavyzdžiui, išsaugosime duomenų lentelę.
save(df, file = "data_exp/duomenys.RData")Į vieną binarinį failą galima išsaugoti keletą R objektų, funkcijoje atskiriant juos kableliu.
save(x, text_vec, mat, file = "data_exp/daug_duomenu.RData")Jei išsaugomų kintamųjų yra daug, jų R aplinkos vardus galima surašyti į character tipo vektorių ir nurodyti vektorių parametrui list.
Kitų formatų binariams failams įrašyti naudojamos specialios funkcijos iš tam tikrų paketų. Čia paminėsime tik dažnai pasitaikančią situaciją - .xlsx formato failų įrašymą.
Jau minėti paketai kaip openxlsx2 ir xlsx turi funkcijas skirtas .xlsx failų įrašymui. Dar vienas paketas, writexl, taip pat turi tokios paskirties funkciją.
Pavyzdžiui, įrašysime df duomenis į failą pvz.xlsx su skirtingų paketų funkcijomis. Jeigu paketai yra įdiegti, bet nenorime jų iškviesti, galima juose esančias funkcijas pasiekti tiesiogiai, naudojant paketas::f() tipo komandą.
openxlsx2::write_xlsx(x = df, file = "data_exp/pvz.xlsx")
xlsx::write.xlsx(x = df, file = "data_exp/pvz.xlsx")
writexl::write_xlsx(x = df, path = "data_exp/pvz.xlsx")Vektorių v ir matricą m įrašykite į vieną binarinį failą vecmat.RData. Užrašykite ir komandos variantą, kuriame naudojamas parametras list.
Iš duomenų rinkinio trees išrinkite pirmus pusę stebinių, parinktine kintamuosiuos Girth ir Volume. Gautą duomenų rinkinį įrašykite į failą puse_medziu.xlsxnaudodami funkciją write_xlsx() iš writexl paketo.