353:R循環(huán)讀取數(shù)據(jù)集

我這段時(shí)間才意識(shí)到學(xué)習(xí)R的方式有點(diǎn)走錯(cuò)了,當(dāng)初想著先把介紹R的書(shū)認(rèn)認(rèn)真真從頭看一遍,或者說(shuō)把R基礎(chǔ)先學(xué)一下,但首先沒(méi)那么多時(shí)間(假的);其次書(shū)上的代碼和數(shù)據(jù)集跟我們項(xiàng)目比差別還是挺大的。

所以我覺(jué)得對(duì)于我們SP來(lái)說(shuō),最好的學(xué)習(xí)方式就是帶著問(wèn)題去學(xué)R,比如我們做項(xiàng)目,首先就是要獲取數(shù)據(jù),這也是我今天要寫(xiě)的;接著是用函數(shù)和語(yǔ)句處理數(shù)據(jù),最終輸出數(shù)據(jù)集。

處理數(shù)據(jù),包括拼接、轉(zhuǎn)換等等,這時(shí)候就存在各種各樣的問(wèn)題,SAS我們知道怎么處理了,這時(shí)候就帶著問(wèn)題,搜一下R中是怎么處理的,找到解決方法之后,最重要的就是自己敲一遍代碼,不管是學(xué)習(xí)SAS還是R都是很重要的一部分。

還有一個(gè)問(wèn)題就是現(xiàn)在項(xiàng)目中幾乎還是用SAS輸出數(shù)據(jù)集,即使你今天學(xué)會(huì)了用R處理數(shù)據(jù),但是說(shuō)不定過(guò)幾天就忘記了,所以還是要有事沒(méi)事就把項(xiàng)目的數(shù)據(jù)拿來(lái)“玩一玩”,敲一敲代碼,多敲幾遍,說(shuō)不定你就像寫(xiě)data步一樣熟悉,便記住了。

一:讀取RAW數(shù)據(jù)庫(kù)

我們做項(xiàng)目,獲取數(shù)據(jù)一般就兩個(gè)途徑,一個(gè)是EDC數(shù)據(jù),一個(gè)是讀取外部excel數(shù)據(jù)。

EDC數(shù)據(jù)我們會(huì)在SAS建立一個(gè)邏輯庫(kù)(其實(shí)也就是一個(gè)文件夾),那么在R中其實(shí)也差不多,只是不需要建立邏輯庫(kù)這么一個(gè)步驟,直接讀取文件夾下的數(shù)據(jù)集就好了,然后再加上一個(gè)將SAS數(shù)據(jù)集轉(zhuǎn)換成數(shù)據(jù)框的這么一個(gè)步驟。

在SAS中,我們是建立一個(gè)RAW 邏輯庫(kù),然后讀取RAW里面的DM發(fā)來(lái)的EDC數(shù)據(jù),比如RAW.DM;RAW.AE;RAW.CM

在R中,我們需要設(shè)立工作路徑,然后讀取路徑下的RAW數(shù)據(jù)。我拿自己課程里的SAS數(shù)據(jù)集舉例子

rm(list = ls()) #刪除一個(gè)或者多個(gè)對(duì)象
library(haven) #加載 讀取SAS數(shù)據(jù)集的一個(gè)庫(kù)


setwd("D:\\R practice\\project")  #設(shè)置工作路徑,相當(dāng)如邏輯庫(kù)RAW
ae<-read_sas('ae.sas7bdat') #讀取sas數(shù)據(jù)集
ae
cm<-read_sas('cm.sas7bdat') #讀取sas數(shù)據(jù)集
cm
image.png

但是這樣存在一個(gè)問(wèn)題,項(xiàng)目中一般有幾十個(gè)RAW數(shù)據(jù)集,如果一個(gè)一個(gè)這樣寫(xiě)效率太低了,而且創(chuàng)建工作路徑之后,SAS數(shù)據(jù)集并沒(méi)有加載到R studio,所以我需要像SAS那樣創(chuàng)建一個(gè)邏輯庫(kù)之后就能訪問(wèn)所有數(shù)據(jù)集,并加載到R studio里面。所以第一想到的就是寫(xiě)個(gè)循環(huán)。

# 設(shè)置文件夾路徑
folder_path <- "D:\\R practice\\project"

# 獲取文件夾下所有 .sas7bdat 文件的文件名
sas_files <- list.files(path = folder_path, pattern = "\\.sas7bdat$", full.names = TRUE)

# 讀取每個(gè) SAS 數(shù)據(jù)集并存儲(chǔ)在列表中
#當(dāng)我們?cè)谘h(huán)處理SAS數(shù)據(jù)集時(shí),然后在循環(huán)外部直接訪問(wèn)數(shù)據(jù)集名稱時(shí),那么這些數(shù)據(jù)集確實(shí)會(huì)顯示不存在,這是因?yàn)樵谘h(huán)內(nèi)部創(chuàng)建的變量在
#循環(huán)結(jié)束后不會(huì)自動(dòng)保存到全局環(huán)境中
#所以我們可以用兩種方法,第一種是用assign函數(shù)將數(shù)據(jù)集存儲(chǔ)在全局環(huán)境中
#第二種是通過(guò)列表

#方法一
for (file in sas_files) {
  sas_data <- read_sas(file)
  dataset_name <- tools::file_path_sans_ext(basename(file)) # 獲取文件名(去掉路徑和拓展名)作為數(shù)據(jù)集名稱

  assign(dataset_name,sas_data)
}

需要注意的是,用for循環(huán)讀取數(shù)據(jù)之后,創(chuàng)建的數(shù)據(jù)集并沒(méi)有輸出到全局環(huán)境之后,所以我們需要用assign函數(shù)加載到全局環(huán)境中去。結(jié)果如圖,可以看到RAE里面的數(shù)據(jù)現(xiàn)在都被加載到R studio里面去了,我們可以直接像SAS那樣點(diǎn)開(kāi)數(shù)據(jù)集,就能查看數(shù)據(jù)了。

image.png
image.png

可以看到,寫(xiě)了一個(gè)循環(huán)之后,相比一個(gè)一個(gè)數(shù)據(jù)集加載方便多了?,F(xiàn)在有了數(shù)據(jù),接下來(lái)就是對(duì)RAW數(shù)據(jù)集進(jìn)行處理了,這個(gè)之后的文章再講。

二:讀取外部excel數(shù)據(jù)

我們做項(xiàng)目,有時(shí)候數(shù)據(jù)可能來(lái)自外部供應(yīng)商,比如血藥濃度數(shù)據(jù),細(xì)胞因子那些,所以我們還需要知道如何用R讀取excel數(shù)據(jù)。在SAS中,用一個(gè)proc import差不多就可以,在R中,需要用到readxl庫(kù)。

讀取外部excel文件,可能會(huì)存在幾個(gè)需求:

  1. 不需要外部文件的列名

  2. 從某一行開(kāi)始讀取

3)日期讀取之后變了格式

4)需要將列名重命名成正常變量名

下面一個(gè)一個(gè)說(shuō)明,我們也不搞什么花里胡哨的技能,readxl能實(shí)現(xiàn)的功能挺多,一個(gè)一個(gè)去說(shuō)明太費(fèi)時(shí)間,也打擊學(xué)習(xí)熱情,我們有什么需求,就只解決提出需求,其余的 閑得蛋疼的時(shí)候可以繼續(xù)摸索。工作中一般就上面4個(gè)需求。

1)不需要外部文件的列名

library(readxl)
example(read_excel)  #查看read_excel有什么功能及對(duì)應(yīng)的例子

testdata1 <- read_excel('D:\\R practice\\project\\test.xlsx',1)
testdata1

testdata2 <- read_excel('D:\\R practice\\project\\test.xlsx',sheet="Sheet1",col_names = FALSE)
testdata2

讀取excel的時(shí)候,你可以用sheet所在的位置,比如程序里面的1代替sheet名,也可以直接指定sheet名稱。然后如果不用文件里面的列名,可以通過(guò)選項(xiàng)col_names = FALSE實(shí)現(xiàn)。

經(jīng)測(cè)試,即使打開(kāi)了EXCEL文件,R也能正常讀取,不像SAS打開(kāi)excel文件就讀取不了了。

image.png
image.png
image.png

R自動(dòng)將列名重命名為...1 ...2 ....,而且發(fā)現(xiàn)最后一列的日期格式讀取也錯(cuò)誤了

2)從某一行讀取,可以通過(guò)skip選項(xiàng),這里我從第二行開(kāi)始讀取

testdata2 <- read_excel('D:\\R practice\\project\\test.xlsx',sheet="Sheet1",col_names = FALSE,skip=2)
image.png

發(fā)現(xiàn)從第二行開(kāi)始讀取的時(shí)候,最后一列的日期格式也展示正確了,可能R是根據(jù)第一行的格式來(lái)確定這一列展示的格式?第二列日期始終展示正確的原因是因?yàn)槲以O(shè)置了這列格式為文本,但是一般外部供應(yīng)商發(fā)過(guò)來(lái)的數(shù)據(jù)大多數(shù)時(shí)候都是不設(shè)置格式的。

3)日期讀取之后變了格式

解決辦法可以像2)一樣從某一行開(kāi)始讀取,另一種方法是讀取后用as.Date函數(shù)處理一下。

需要注意,如果你把列名讀取進(jìn)來(lái)的話,在轉(zhuǎn)換的時(shí)候會(huì)報(bào)錯(cuò),因?yàn)榈谝恍小啊焙瞬槿掌凇鞭D(zhuǎn)換不了。會(huì)報(bào)這個(gè)錯(cuò)

“Error in charToDate(x) : 字符串的格式不夠標(biāo)準(zhǔn)明確”

我們先看一下只有數(shù)字的數(shù)據(jù)怎么轉(zhuǎn)換,沒(méi)有中文名稱那一行了

image.png
testdata4 <- read_excel('D:\\R practice\\project\\test.xlsx',sheet="Sheet2",col_names = FALSE)
testdata4[[4]] <- as.Date(testdata4[[4]], origin = "1899-12-30")

excel將1900年1月1日視為第一天,但實(shí)際上它從1899年12月30日開(kāi)始計(jì)數(shù)。其實(shí)excel日期格式的數(shù)據(jù)導(dǎo)入到SAS也有一個(gè)時(shí)間差,也需要特殊處理一下。

如果還需要輸出第一行的中文列名,需要注意的是,as.date轉(zhuǎn)換的日期是數(shù)值型,但是這列在讀取進(jìn)來(lái)的時(shí)候是字符型的,所以拼在一起的時(shí)候會(huì)報(bào)上面的錯(cuò),所以還需要將數(shù)值型日期轉(zhuǎn)換成字符型。

testdata3 <- read_excel('D:\\R practice\\project\\test.xlsx',sheet="Sheet1",col_names = FALSE)

date_column <- testdata3[[4]]
# 檢查日期列的數(shù)據(jù)類型
if (is.character(date_column)) {
  # 將第二行及其后的數(shù)據(jù)轉(zhuǎn)換為數(shù)字
  date_column_numeric <- as.numeric(date_column[-1])
  
  # 將數(shù)字轉(zhuǎn)換為日期格式
  date_column_dates <- as.Date(date_column_numeric, origin = "1899-12-30")
  
  # 將為日期格式轉(zhuǎn)換為字符型
  date_column_dates2<-as.character(date_column_dates)
  # 將轉(zhuǎn)換后的日期放回?cái)?shù)據(jù)框中
  testdata3[[4]][-1] <- date_column_dates2
  
}
image.png
image.png

4)需要將列名重命名成正常變量名

R中重命名有好幾種方式,在SAS中應(yīng)該只有rename和在data步中創(chuàng)建新變量等于舊變量。

一種是直接使用readxl庫(kù)重命名

#重命名列名
testdata5 <- read_excel('D:\\R practice\\project\\test.xlsx',sheet="Sheet1",col_names = FALSE)
colnames(testdata5) #查看原始數(shù)據(jù)集名稱

#readxl庫(kù)
colnames(testdata5) <- c("studyid", "lbdtc", "aval","checkdate")

一種是使用#dplyr庫(kù)里的rename函數(shù)(記得提前加載dplyr到R),這時(shí)候前面的變量名是你要rename的名稱,跟SAS還不一樣。

testdata5_1 <- testdata5 %>% rename(studyid = ...1,  lbdtc= ...2,aval=...3,checd=...4)
image.png

好了,上面就是用R導(dǎo)入數(shù)據(jù)的幾種方式。

祝您中秋愉快!SAS PRO竭誠(chéng)為您服務(wù)!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容