7 Veri içe aktarma
7.1 Giriş
R paketlerinin sağladığı verilerle çalışmak, veri bilimi araçlarını öğrenmenin harika bir yoludur; ancak bir noktada öğrendiklerinizi kendi verilerinize uygulamak istersiniz. Bu bölümde veri dosyalarını R’a içe aktarmanın temellerini öğreneceksiniz.
Bu bölüm özellikle tablo biçimindeki düz metin dosyalarını okumaya odaklanır. Sütun adları, sütun türleri ve eksik veriler gibi özellikleri ele almaya yönelik pratik önerilerle başlayacağız. Ardından, birden fazla dosyadan aynı anda veri okumayı ve R’dan bir dosyaya veri yazmayı öğreneceksiniz. Son olarak, R’da veri çerçevelerini elle nasıl oluşturacağınızı öğreneceksiniz.
7.1.1 Ön koşullar
Bu bölümde çekirdek tidyverse’in bir parçası olan readr paketiyle düz metin dosyalarını R’a içe aktarmayı öğreneceksiniz.
7.2 Bir dosyadan veri okuma
Başlangıçta en yaygın tablo biçimli veri dosyası türüne odaklanacağız: virgülle ayrılmış değerler (comma-separated values) anlamına gelen CSV. Basit bir CSV dosyası şuna benzer. Genellikle başlık satırı (header row) olarak adlandırılan ilk satır sütun adlarını verir ve ardından gelen altı satır veriyi sağlar. Sütunlar virgülle ayrılır; başka bir deyişle virgül burada ayraç (delimiter) görevi görür.
Student ID,Full Name,favourite.food,mealPlan,AGE
1,Sunil Huffmann,Strawberry yoghurt,Lunch only,4
2,Barclay Lynn,French fries,Lunch only,5
3,Jayendra Lyne,N/A,Breakfast and lunch,7
4,Leon Rossini,Anchovies,Lunch only,
5,Chidiegwu Dunkel,Pizza,Breakfast and lunch,five
6,Güvenç Attila,Ice cream,Lunch only,6
Tablo 7.1 aynı verinin bir tablo olarak temsilini gösterir.
| Student ID | Full Name | favourite.food | mealPlan | AGE |
|---|---|---|---|---|
| 1 | Sunil Huffmann | Strawberry yoghurt | Lunch only | 4 |
| 2 | Barclay Lynn | French fries | Lunch only | 5 |
| 3 | Jayendra Lyne | N/A | Breakfast and lunch | 7 |
| 4 | Leon Rossini | Anchovies | Lunch only | NA |
| 5 | Chidiegwu Dunkel | Pizza | Breakfast and lunch | five |
| 6 | Güvenç Attila | Ice cream | Lunch only | 6 |
Bu dosyayı read_csv()’i kullanarak R’a okuyabiliriz. İlk argüman en önemlisidir: dosyanın yolu. Yolu dosyanın adresi olarak düşünebilirsiniz: Dosyanın adı students.csv’dir ve dosya data klasöründe bulunur.
students <- read_csv("data/students.csv")
#> Rows: 6 Columns: 5
#> ── Column specification ─────────────────────────────────────────────────────
#> Delimiter: ","
#> chr (4): Full Name, favourite.food, mealPlan, AGE
#> dbl (1): Student ID
#>
#> ℹ 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.Yukarıdaki kod, projenizde bir data klasöründe students.csv dosyasına sahipseniz çalışacaktır. students.csv dosyasını https://pos.it/r4ds-students-csv adresinden indirebilir veya onu doğrudan o URL’den şu şekilde okuyabilirsiniz:
students <- read_csv("https://pos.it/r4ds-students-csv")read_csv() çalıştırıldığında verilerin satır ve sütun sayısını, kullanılan ayracı ve sütun belirtimini (içerdikleri veri türüne göre gruplanmış sütun adlarını) açıklayan bir mesaj görüntüler. Ayrıca tam sütun belirtimini nasıl görebileceğinizi ve bu mesajı nasıl gizleyebileceğinizi de açıklar. Bu mesaj readr’ın ayrılmaz bir parçasıdır ve Bölüm 7.3 bölümünde ona geri döneceğiz.
7.2.1 Pratik öneriler
Verileri okuduktan sonraki ilk adım, analizinizin geri kalanında çalışmayı kolaylaştıracak bir dönüşüm yapmak olur. Bunu aklımızda tutarak students verisine tekrar bir bakalım.
students
#> # A tibble: 6 × 5
#> `Student ID` `Full Name` favourite.food mealPlan AGE
#> <dbl> <chr> <chr> <chr> <chr>
#> 1 1 Sunil Huffmann Strawberry yoghurt Lunch only 4
#> 2 2 Barclay Lynn French fries Lunch only 5
#> 3 3 Jayendra Lyne N/A Breakfast and lunch 7
#> 4 4 Leon Rossini Anchovies Lunch only <NA>
#> 5 5 Chidiegwu Dunkel Pizza Breakfast and lunch five
#> 6 6 Güvenç Attila Ice cream Lunch only 6favourite.food sütununda çeşitli yiyecek adlarının yanı sıra, aslında R’ın “mevcut değil” (not available) olarak tanıyacağı gerçek bir NA olması gereken N/A karakter dizisi bulunur. Bu, na argümanını kullanarak ele alabileceğimiz bir şeydir. Varsayılan olarak, read_csv() bu veri kümesinde yalnızca boş karakter dizilerini ("") NA olarak tanır ve "N/A" karakter dizisini de tanımasını istiyoruz.
students <- read_csv("data/students.csv", na = c("N/A", ""))
students
#> # A tibble: 6 × 5
#> `Student ID` `Full Name` favourite.food mealPlan AGE
#> <dbl> <chr> <chr> <chr> <chr>
#> 1 1 Sunil Huffmann Strawberry yoghurt Lunch only 4
#> 2 2 Barclay Lynn French fries Lunch only 5
#> 3 3 Jayendra Lyne <NA> Breakfast and lunch 7
#> 4 4 Leon Rossini Anchovies Lunch only <NA>
#> 5 5 Chidiegwu Dunkel Pizza Breakfast and lunch five
#> 6 6 Güvenç Attila Ice cream Lunch only 6Student ID ve Full Name sütunlarının ters tırnak (backtick) içine alındığını da fark etmiş olabilirsiniz. Bunun nedeni boşluk içermeleri ve R’ın değişken adlarına ilişkin olağan kurallarına uymamalarıdır; bunlar söz dizimsel olmayan (non-syntactic) adlardır. Bu değişkenlere atıfta bulunmak için, onları ters tırnaklarla, `, çevrelemeniz gerekir:
students |>
rename(
student_id = `Student ID`,
full_name = `Full Name`
)
#> # A tibble: 6 × 5
#> student_id full_name favourite.food mealPlan AGE
#> <dbl> <chr> <chr> <chr> <chr>
#> 1 1 Sunil Huffmann Strawberry yoghurt Lunch only 4
#> 2 2 Barclay Lynn French fries Lunch only 5
#> 3 3 Jayendra Lyne <NA> Breakfast and lunch 7
#> 4 4 Leon Rossini Anchovies Lunch only <NA>
#> 5 5 Chidiegwu Dunkel Pizza Breakfast and lunch five
#> 6 6 Güvenç Attila Ice cream Lunch only 6Alternatif bir yaklaşım, hepsini bir kerede snake case’e dönüştürmek için bazı sezgisel yöntemler kullanan janitor::clean_names()’i kullanmaktır1.
students |> janitor::clean_names()
#> # A tibble: 6 × 5
#> student_id full_name favourite_food meal_plan age
#> <dbl> <chr> <chr> <chr> <chr>
#> 1 1 Sunil Huffmann Strawberry yoghurt Lunch only 4
#> 2 2 Barclay Lynn French fries Lunch only 5
#> 3 3 Jayendra Lyne <NA> Breakfast and lunch 7
#> 4 4 Leon Rossini Anchovies Lunch only <NA>
#> 5 5 Chidiegwu Dunkel Pizza Breakfast and lunch five
#> 6 6 Güvenç Attila Ice cream Lunch only 6Veriyi okuduktan sonraki bir başka yaygın görev, değişken türlerini göz önünde bulundurmaktır. Örneğin, meal_plan, bilinen bir olası değerler kümesine sahip kategorik bir değişkendir ve R’da bir faktör olarak temsil edilmelidir:
students |>
janitor::clean_names() |>
mutate(meal_plan = factor(meal_plan))
#> # A tibble: 6 × 5
#> student_id full_name favourite_food meal_plan age
#> <dbl> <chr> <chr> <fct> <chr>
#> 1 1 Sunil Huffmann Strawberry yoghurt Lunch only 4
#> 2 2 Barclay Lynn French fries Lunch only 5
#> 3 3 Jayendra Lyne <NA> Breakfast and lunch 7
#> 4 4 Leon Rossini Anchovies Lunch only <NA>
#> 5 5 Chidiegwu Dunkel Pizza Breakfast and lunch five
#> 6 6 Güvenç Attila Ice cream Lunch only 6meal_plan değişkenindeki değerlerin aynı kaldığına, ama değişken adının altında belirtilen değişken türünün karakterden (<chr>) faktöre (<fct>) değiştiğine dikkat edin. Faktörler hakkında Bölüm 16 bölümünde daha fazla bilgi edineceksiniz.
Bu veriyi analiz etmeden önce, muhtemelen age sütununu düzeltmek isteyeceksiniz. Şu anda age, gözlemlerden biri sayısal 5 yerine five olarak yazıldığından, bir karakter değişkenidir. Bu sorunu düzeltmenin ayrıntılarını Bölüm 20 bölümünde tartışıyoruz.
students <- students |>
janitor::clean_names() |>
mutate(
meal_plan = factor(meal_plan),
age = parse_number(if_else(age == "five", "5", age))
)
students
#> # A tibble: 6 × 5
#> student_id full_name favourite_food meal_plan age
#> <dbl> <chr> <chr> <fct> <dbl>
#> 1 1 Sunil Huffmann Strawberry yoghurt Lunch only 4
#> 2 2 Barclay Lynn French fries Lunch only 5
#> 3 3 Jayendra Lyne <NA> Breakfast and lunch 7
#> 4 4 Leon Rossini Anchovies Lunch only NA
#> 5 5 Chidiegwu Dunkel Pizza Breakfast and lunch 5
#> 6 6 Güvenç Attila Ice cream Lunch only 6Buradaki yeni fonksiyon, üç argüman alan if_else() fonksiyonudur. İlk argüman olan test, mantıksal bir vektör olmalıdır. Sonuçta test değeri TRUE olduğunda ikinci argümanın (yes), FALSE olduğunda ise üçüncü argümanın (no) değeri kullanılır. Burada, age "five" karakter dizisiyse onu "5" yap, değilse age olarak bırak diyoruz. if_else() ve mantıksal vektörler hakkında Bölüm 12 bölümünde daha fazla bilgi edineceksiniz.
7.2.2 Diğer argümanlar
Bahsetmemiz gereken birkaç önemli argüman daha var ve önce size kullanışlı bir numara gösterirsek bunları göstermek daha kolay olacak: read_csv(), oluşturup bir CSV dosyası gibi biçimlendirdiğiniz metin karakter dizilerini okuyabilir:
read_csv(
"a,b,c
1,2,3
4,5,6"
)
#> Warning: The `file` argument of `read_csv()` should use `I()` for literal data as of
#> readr 2.2.0.
#>
#> # Bad (for example):
#> read_csv("x,y\n1,2")
#>
#> # Good:
#> read_csv(I("x,y\n1,2"))
#> # A tibble: 2 × 3
#> a b c
#> <dbl> <dbl> <dbl>
#> 1 1 2 3
#> 2 4 5 6read_csv() genellikle verilerin ilk satırını sütun adları olarak kullanır; bu çok yaygın bir kuraldır. Ancak dosyanın başında birkaç satır üst veri bulunması da olağandır. İlk n satırı atlamak için skip = n kullanabilir veya (örneğin) # ile başlayan tüm satırları düşürmek için comment = "#" kullanabilirsiniz:
Diğer durumlarda, verinin sütun adları olmayabilir. read_csv()’e ilk satırı başlık olarak ele almamasını ve bunun yerine X1’den Xn’e kadar sırayla etiketlemesini söylemek için col_names = FALSE kullanabilirsiniz:
read_csv(
"1,2,3
4,5,6",
col_names = FALSE
)
#> # A tibble: 2 × 3
#> X1 X2 X3
#> <dbl> <dbl> <dbl>
#> 1 1 2 3
#> 2 4 5 6Alternatif olarak, col_names’e sütun adları olarak kullanılacak bir karakter vektörü de geçebilirsiniz:
Bu argümanlar, pratikte karşılaşacağınız CSV dosyalarının çoğunu okumak için bilmeniz gereken her şeydir. (Geri kalanı için, .csv dosyanızı dikkatlice incelemeniz ve read_csv()’in diğer pek çok argümanının dokümantasyonunu okumanız gerekecek.)
7.2.3 Diğer dosya türleri
read_csv() fonksiyonunda ustalaştıktan sonra readr’ın diğer fonksiyonlarını kullanmak kolaydır; yalnızca hangi fonksiyonu çağıracağınızı bilmeniz gerekir:
read_csv2()noktalı virgülle ayrılmış dosyaları okur. Bunlar, alanları ayırmak için,yerine;kullanır ve ondalık işareti olarak,kullanan ülkelerde yaygındır.read_tsv()sekmeyle ayrılmış dosyaları okur.read_delim(), herhangi bir ayraç kullanan dosyaları okur; ayracı belirtmezseniz otomatik olarak tahmin etmeye çalışır.read_fwf()sabit genişlikli dosyaları okur. Alanlarıfwf_widths()ile genişliklerine göre veyafwf_positions()ile konumlarına göre belirtebilirsiniz.read_table(), sütunların boşlukla ayrıldığı sabit genişlikli dosyaların yaygın bir varyasyonunu okur.read_log()Apache tarzı günlük (log) dosyalarını okur.
7.2.4 Alıştırmalar
Alanların “|” ile ayrıldığı bir dosyayı okumak için hangi fonksiyonu kullanırdınız?
file,skipvecommentdışında,read_csv()veread_tsv()’nin ortak olarak başka hangi argümanları var?read_fwf()’in en önemli argümanları nelerdir?-
Bazen bir CSV dosyasındaki karakter dizileri virgül içerir. Sorun yaratmalarını önlemek için,
"veya'gibi bir tırnak karakteriyle çevrelenmeleri gerekir. Varsayılan olarak,read_csv()tırnak karakterinin"olacağını varsayar. Aşağıdaki metni bir veri çerçevesine okumak için,read_csv()’e hangi argümanı belirtmeniz gerekir?"x,y\n1,'a,b'" -
Aşağıdaki satır içi CSV dosyalarının her birinde neyin yanlış olduğunu belirleyin. Kodu çalıştırdığınızda ne olur?
-
Aşağıdaki veri çerçevesinde sözdizimsel olmayan isimlere atıfta bulunmayı şu şekilde pratik edin:
-
1adlı değişkeni çıkarın. -
1’e karşı2’nin bir saçılım grafiğini çizin. -
2’nin1’e bölünmesiyle elde edilen3adlı yeni bir sütun oluşturun. - Sütunları
one,twovethreeolarak yeniden adlandırın.
-
7.3 Sütun türlerini denetleme
Bir CSV dosyası, her değişkenin türü hakkında herhangi bir bilgi içermez (yani mantıksal mı, sayı mı, karakter dizisi mi vb.), bu yüzden readr türü tahmin etmeye çalışır. Bu bölüm, tahmin sürecinin nasıl çalıştığını, başarısız olmasına neden olan bazı yaygın sorunların nasıl çözüleceğini ve gerekirse sütun türlerini kendinizin nasıl sağlayacağını açıklar. Son olarak readr dosyayı doğru biçimde ayrıştıramıyorsa ve dosya yapısı hakkında daha fazla bilgi edinmeniz gerekiyorsa yararlanabileceğiniz birkaç genel stratejiden söz edeceğiz.
7.3.1 Türleri tahmin etme
readr, sütun türlerini bulmak için sezgisel bir yöntem kullanır. Her sütun için, eksik değerleri göz ardı ederek, ilk satırdan sona kadar eşit aralıklarla dağılmış 1.000 satırın2 değerlerini çeker. Ardından şu soruları sırayla ele alır:
- Yalnızca
F,T,FALSEveyaTRUEmü içeriyor (büyük/küçük harf gözetmeksizin)? Öyleyse, bir mantıksaldır. - Yalnızca sayılar mı içeriyor (örneğin,
1,-4.5,5e6,Inf)? Öyleyse, bir sayıdır. - ISO8601 standardıyla eşleşiyor mu? Öyleyse, bir tarih veya tarih-saattir. (Tarih-saatlere Bölüm 17.2 bölümünde daha ayrıntılı geri döneceğiz.)
- Aksi takdirde, bir karakter dizisi olmalıdır.
Bu davranışı bu basit örnekte eylem halinde görebilirsiniz:
read_csv("
logical,numeric,date,string
TRUE,1,2021-01-15,abc
false,4.5,2021-02-15,def
T,Inf,2021-02-16,ghi
")
#> # A tibble: 3 × 4
#> logical numeric date string
#> <lgl> <dbl> <date> <chr>
#> 1 TRUE 1 2021-01-15 abc
#> 2 FALSE 4.5 2021-02-15 def
#> 3 TRUE Inf 2021-02-16 ghiBu sezgisel yöntem temiz veri kümelerinde iyi çalışır; ancak gerçek yaşamda çeşit çeşit tuhaf ayrıştırma hatasıyla karşılaşırsınız.
7.3.2 Eksik değerler, sütun türleri ve sorunlar
Sütun türü tespitinin en yaygın başarısızlık biçimi, sütunun beklenmedik değerler içermesi ve daha özel bir tür yerine karakter sütunu olarak okunmasıdır. Bunun en yaygın nedenlerinden biri, readr’ın beklediği NA dışında bir şey kullanılarak kaydedilmiş bir eksik değerdir.
Bu basit, tek sütunlu CSV dosyasını örnek olarak ele alalım:
simple_csv <- "
x
10
.
20
30"Onu herhangi bir ek argüman olmadan okursak, x bir karakter sütunu haline gelir:
read_csv(simple_csv)
#> # A tibble: 4 × 1
#> x
#> <chr>
#> 1 10
#> 2 .
#> 3 20
#> 4 30Bu çok küçük durumda, eksik değeri, .’yi, kolayca görebilirsiniz. Ama aralarına serpiştirilmiş .’lerle temsil edilen yalnızca birkaç eksik değere sahip binlerce satırınız olsaydı ne olurdu? Bir yaklaşım, readr’a x’in sayısal bir sütun olduğunu söylemek ve ardından nerede başarısız olduğunu görmektir. Bunu, adları CSV dosyasındaki sütun adlarıyla eşleşen, adlandırılmış bir liste alan col_types argümanıyla yapabilirsiniz:
df <- read_csv(
simple_csv,
col_types = list(x = col_double())
)
#> Warning: One or more parsing issues, call `problems()` on your data frame for
#> details, e.g.:
#> dat <- vroom(...)
#> problems(dat)Şimdi read_csv(), bir sorun olduğunu bildiriyor ve problems() ile daha fazlasını öğrenebileceğimizi söylüyor:
problems(df)
#> # A tibble: 1 × 5
#> row col expected actual file
#> <int> <int> <chr> <chr> <chr>
#> 1 3 1 a double . /tmp/RtmpblFazD/vroom-chr-to-file-1fc325b1ab44Bu bize, readr’ın bir double beklediği ama bir . aldığı satır 3, sütun 1’de bir sorun olduğunu söylüyor. Bu, bu veri kümesinin eksik değerler için . kullandığını düşündürüyor. Bu yüzden na = "." ayarladığımızda, otomatik tahmin başarılı olur ve bize istediğimiz sayısal sütunu verir:
read_csv(simple_csv, na = ".")
#> # A tibble: 4 × 1
#> x
#> <dbl>
#> 1 10
#> 2 NA
#> 3 20
#> 4 307.3.3 Sütun türleri
readr, kullanmanız için toplam dokuz sütun türü sağlar:
-
col_logical()vecol_double(), mantıksal değerleri ve gerçek sayıları okur. Görece nadiren ihtiyaç duyulurlar (yukarıdaki durum hariç), çünkü readr genellikle bunları sizin için tahmin edecektir. -
col_integer()tam sayıları okur. Bu kitapta tam sayıları ve double’ları nadiren ayırt ediyoruz, çünkü işlevsel olarak eşdeğerler; ama tam sayıları açıkça okumak bazen yararlı olabilir, çünkü double’ların yarısı kadar bellek kaplarlar. -
col_character()karakter dizilerini okur. Bir nesneyi tanımlayan ama üzerinde matematiksel işlemler uygulamak mantıklı olmayan uzun rakam dizileri olan, yani sayısal bir tanımlayıcı olan bir sütununuz olduğunda bunu açıkça belirtmek yararlı olabilir. Örnekler arasında telefon numaraları, sosyal güvenlik numaraları, kredi kartı numaraları vb. bulunur. -
col_factor(),col_date()vecol_datetime(), sırasıyla faktörler, tarihler ve tarih-saatler oluşturur; bu veri türlerine Bölüm 16 ve Bölüm 17 bölümlerinde geldiğimizde bunlar hakkında daha fazla bilgi edineceksiniz. -
col_number(), sayısal olmayan bileşenleri yok sayan hoşgörülü bir sayısal ayrıştırıcıdır ve özellikle para birimleri için yararlıdır. Bu konuda Bölüm 13 bölümünde daha fazla bilgi edineceksiniz. -
col_skip(), bir sütunu atlayarak sonuca dahil edilmemesini sağlar; bu, büyük bir CSV dosyanız varsa ve yalnızca bazı sütunları kullanmak istiyorsanız veriyi okumayı hızlandırmak için yararlı olabilir.
list() yerine cols() kullanıp .default değerini belirterek tür tahmini yapan varsayılan sezgisel yöntemi geçersiz kılabilirsiniz:
another_csv <- "
x,y,z
1,2,3"
read_csv(
another_csv,
col_types = cols(.default = col_character())
)
#> # A tibble: 1 × 3
#> x y z
#> <chr> <chr> <chr>
#> 1 1 2 3Bir başka yararlı yardımcı, yalnızca belirttiğiniz sütunları okuyacak olan cols_only()’dur:
read_csv(
another_csv,
col_types = cols_only(x = col_character())
)
#> # A tibble: 1 × 1
#> x
#> <chr>
#> 1 17.4 Birden fazla dosyadan veri okuma
Bazen veriniz tek bir dosyada bulunmak yerine birden fazla dosyaya bölünmüştür. Örneğin, birden fazla aya ait satış verileriniz olabilir; her ayın verisi ayrı bir dosyada: Ocak için 01-sales.csv, Şubat için 02-sales.csv ve Mart için 03-sales.csv. read_csv() ile bu verileri bir kerede okuyabilir ve tek bir veri çerçevesinde üst üste yığabilirsiniz.
sales_files <- c("data/01-sales.csv", "data/02-sales.csv", "data/03-sales.csv")
read_csv(sales_files, id = "file")
#> # A tibble: 19 × 6
#> file month year brand item n
#> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
#> 1 data/01-sales.csv January 2019 1 1234 3
#> 2 data/01-sales.csv January 2019 1 8721 9
#> 3 data/01-sales.csv January 2019 1 1822 2
#> 4 data/01-sales.csv January 2019 2 3333 1
#> 5 data/01-sales.csv January 2019 2 2156 9
#> 6 data/01-sales.csv January 2019 2 3987 6
#> # ℹ 13 more rowsYine, yukarıdaki kod, projenizde bir data klasöründe CSV dosyalarına sahipseniz çalışacaktır. Bu dosyaları https://pos.it/r4ds-01-sales, https://pos.it/r4ds-02-sales ve https://pos.it/r4ds-03-sales adreslerinden indirebilir veya onları doğrudan şu şekilde okuyabilirsiniz:
id argümanı, ortaya çıkan veri çerçevesine file adlı yeni bir sütun ekler; bu sütun verilerin hangi dosyadan geldiğini belirtir. Bu, okuduğunuz dosyaların, gözlemleri orijinal kaynaklarına geri izlemenize yardımcı olacak bir tanımlayıcı sütuna sahip olmadığı durumlarda özellikle yararlıdır.
Okumak istediğiniz çok sayıda dosyanız varsa, adlarını bir liste olarak yazmak külfetli hale gelebilir. Bunun yerine, dosya adlarında bir kalıp eşleştirerek dosyaları sizin için bulmak üzere temel list.files() fonksiyonunu kullanabilirsiniz. Bu kalıplar hakkında Bölüm 15 bölümünde daha fazla bilgi edineceksiniz.
sales_files <- list.files("data", pattern = "sales\\.csv$", full.names = TRUE)
sales_files
#> [1] "data/01-sales.csv" "data/02-sales.csv" "data/03-sales.csv"7.5 Bir dosyaya yazma
readr ayrıca veriyi diske geri yazmak için iki yararlı fonksiyonla birlikte gelir: write_csv() ve write_tsv(). Bu fonksiyonların en önemli argümanları x (kaydedilecek veri çerçevesi) ve file’dır (kaydedileceği konum). Ayrıca eksik değerlerin na ile nasıl yazılacağını ve verileri mevcut bir dosyanın sonuna eklemek isteyip istemediğinizi de belirtebilirsiniz.
write_csv(students, "students.csv")Şimdi o csv dosyasını tekrar okuyalım. Az önce kurduğunuz değişken türü bilgisinin, CSV’ye kaydettiğinizde kaybolduğuna dikkat edin; çünkü düz metin dosyasından okuyarak tekrar baştan başlıyorsunuz:
students
#> # A tibble: 6 × 5
#> student_id full_name favourite_food meal_plan age
#> <dbl> <chr> <chr> <fct> <dbl>
#> 1 1 Sunil Huffmann Strawberry yoghurt Lunch only 4
#> 2 2 Barclay Lynn French fries Lunch only 5
#> 3 3 Jayendra Lyne <NA> Breakfast and lunch 7
#> 4 4 Leon Rossini Anchovies Lunch only NA
#> 5 5 Chidiegwu Dunkel Pizza Breakfast and lunch 5
#> 6 6 Güvenç Attila Ice cream Lunch only 6
write_csv(students, "students-2.csv")
read_csv("students-2.csv")
#> # A tibble: 6 × 5
#> student_id full_name favourite_food meal_plan age
#> <dbl> <chr> <chr> <chr> <dbl>
#> 1 1 Sunil Huffmann Strawberry yoghurt Lunch only 4
#> 2 2 Barclay Lynn French fries Lunch only 5
#> 3 3 Jayendra Lyne <NA> Breakfast and lunch 7
#> 4 4 Leon Rossini Anchovies Lunch only NA
#> 5 5 Chidiegwu Dunkel Pizza Breakfast and lunch 5
#> 6 6 Güvenç Attila Ice cream Lunch only 6Bu durum CSV dosyalarını ara sonuçları önbelleğe almak için biraz güvenilmez kılar: Dosyayı her yüklediğinizde sütun belirtimini yeniden oluşturmanız gerekir. İki temel alternatif vardır:
-
write_rds()veread_rds(), temelreadRDS()vesaveRDS()fonksiyonları için tutarlı bir arayüz sunan sarmalayıcılardır. Verileri RDS adı verilen, R’a özgü ikili dosya biçiminde saklarlar. Bu, nesneyi yeniden yüklediğinizde, sakladığınız tamamen aynı R nesnesini yüklediğiniz anlamına gelir.write_rds(students, "students.rds") read_rds("students.rds") #> # A tibble: 6 × 5 #> student_id full_name favourite_food meal_plan age #> <dbl> <chr> <chr> <fct> <dbl> #> 1 1 Sunil Huffmann Strawberry yoghurt Lunch only 4 #> 2 2 Barclay Lynn French fries Lunch only 5 #> 3 3 Jayendra Lyne <NA> Breakfast and lunch 7 #> 4 4 Leon Rossini Anchovies Lunch only NA #> 5 5 Chidiegwu Dunkel Pizza Breakfast and lunch 5 #> 6 6 Güvenç Attila Ice cream Lunch only 6 -
arrow paketi, programlama dilleri arasında paylaşılabilen hızlı bir ikili dosya biçimi olan Parquet dosyalarını okuyup yazmanızı sağlar. arrow’a Bölüm 22 bölümünde daha derinlemesine geri döneceğiz.
library(arrow) write_parquet(students, "students.parquet") read_parquet("students.parquet") #> # A tibble: 6 × 5 #> student_id full_name favourite_food meal_plan age #> <dbl> <chr> <chr> <fct> <dbl> #> 1 1 Sunil Huffmann Strawberry yoghurt Lunch only 4 #> 2 2 Barclay Lynn French fries Lunch only 5 #> 3 3 Jayendra Lyne NA Breakfast and lunch 7 #> 4 4 Leon Rossini Anchovies Lunch only NA #> 5 5 Chidiegwu Dunkel Pizza Breakfast and lunch 5 #> 6 6 Güvenç Attila Ice cream Lunch only 6
Parquet genellikle RDS’den çok daha hızlıdır ve R dışında da kullanılabilir; ancak arrow paketini gerektirir.
7.6 Elle veri girişi
Bazen R scriptinizin içinde veri girerek bir tibble’ı “elle” oluşturmanız gerekir. Bunu yapmanıza yardımcı olacak, tibble’ı sütunlara göre mi yoksa satırlara göre mi düzenlediğinize göre farklılık gösteren iki yararlı fonksiyon vardır. tibble() sütun bazında çalışır:
Verileri sütunlara göre düzenlemek satırlar arasındaki ilişkileri görmeyi zorlaştırabilir. Bir alternatif, verileri satır satır düzenlemenizi sağlayan ve transposed tibble (devrik tibble) ifadesinin kısaltması olan tribble() fonksiyonudur. tribble(), kodda veri girişi için özelleştirilmiştir: sütun başlıkları ~ ile başlar ve girdiler virgüllerle ayrılır. Bu, az miktarda veriyi okunması kolay bir formda düzenlemeyi mümkün kılar:
tribble(
~x, ~y, ~z,
1, "h", 0.08,
2, "m", 0.83,
5, "g", 0.60
)
#> # A tibble: 3 × 3
#> x y z
#> <dbl> <chr> <dbl>
#> 1 1 h 0.08
#> 2 2 m 0.83
#> 3 5 g 0.67.7 Özet
Bu bölümde, read_csv() ile CSV dosyalarını nasıl yükleyeceğinizi ve tibble() ile tribble() ile kendi veri girişinizi nasıl yapacağınızı öğrendiniz. CSV dosyalarının nasıl çalıştığını, karşılaşabileceğiniz bazı sorunları ve bunların nasıl aşılacağını öğrendiniz. Bu kitapta veri içe aktarmaya birkaç kez daha döneceğiz: Excel ve Google E-Tablolar’dan Bölüm 20, veritabanlarından veri yüklemeyi göstereceğimiz Bölüm 21, Parquet dosyalarından Bölüm 22, JSON’dan Bölüm 23 ve web sitelerinden Bölüm 24.
Kitabın bu bölümünün neredeyse sonuna geldik; ama ele almamız gereken önemli bir son konu daha var: nasıl yardım alınır. Bu yüzden bir sonraki bölümde yardım arayabileceğiniz iyi kaynakları, yararlı yanıt alma olasılığınızı artıracak yeniden üretilebilir bir örneği (reprex) nasıl oluşturacağınızı ve R dünyasını takip etmeye yönelik bazı genel önerileri öğreneceksiniz.