353:R循环读取数据集

我这段时间才意识到学习R的方式有点走错了,当初想着先把介绍R的书认认真真从头看一遍,或者说把R基础先学一下,但首先没那么多时间(假的);其次书上的代码和数据集跟我们项目比差别还是挺大的。

所以我觉得对于我们SP来说,最好的学习方式就是带着问题去学R,比如我们做项目,首先就是要获取数据,这也是我今天要写的;接着是用函数和语句处理数据,最终输出数据集。

处理数据,包括拼接、转换等等,这时候就存在各种各样的问题,SAS我们知道怎么处理了,这时候就带着问题,搜一下R中是怎么处理的,找到解决方法之后,最重要的就是自己敲一遍代码,不管是学习SAS还是R都是很重要的一部分。

还有一个问题就是现在项目中几乎还是用SAS输出数据集,即使你今天学会了用R处理数据,但是说不定过几天就忘记了,所以还是要有事没事就把项目的数据拿来“玩一玩”,敲一敲代码,多敲几遍,说不定你就像写data步一样熟悉,便记住了。

一:读取RAW数据库

我们做项目,获取数据一般就两个途径,一个是EDC数据,一个是读取外部excel数据。

EDC数据我们会在SAS建立一个逻辑库(其实也就是一个文件夹),那么在R中其实也差不多,只是不需要建立逻辑库这么一个步骤,直接读取文件夹下的数据集就好了,然后再加上一个将SAS数据集转换成数据框的这么一个步骤。

在SAS中,我们是建立一个RAW 逻辑库,然后读取RAW里面的DM发来的EDC数据,比如RAW.DM;RAW.AE;RAW.CM

在R中,我们需要设立工作路径,然后读取路径下的RAW数据。我拿自己课程里的SAS数据集举例子

rm(list = ls()) #删除一个或者多个对象
library(haven) #加载 读取SAS数据集的一个库


setwd("D:\\R practice\\project")  #设置工作路径,相当如逻辑库RAW
ae<-read_sas('ae.sas7bdat') #读取sas数据集
ae
cm<-read_sas('cm.sas7bdat') #读取sas数据集
cm
image.png

但是这样存在一个问题,项目中一般有几十个RAW数据集,如果一个一个这样写效率太低了,而且创建工作路径之后,SAS数据集并没有加载到R studio,所以我需要像SAS那样创建一个逻辑库之后就能访问所有数据集,并加载到R studio里面。所以第一想到的就是写个循环。

# 设置文件夹路径
folder_path <- "D:\\R practice\\project"

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

# 读取每个 SAS 数据集并存储在列表中
#当我们在循环处理SAS数据集时,然后在循环外部直接访问数据集名称时,那么这些数据集确实会显示不存在,这是因为在循环内部创建的变量在
#循环结束后不会自动保存到全局环境中
#所以我们可以用两种方法,第一种是用assign函数将数据集存储在全局环境中
#第二种是通过列表

#方法一
for (file in sas_files) {
  sas_data <- read_sas(file)
  dataset_name <- tools::file_path_sans_ext(basename(file)) # 获取文件名(去掉路径和拓展名)作为数据集名称

  assign(dataset_name,sas_data)
}

需要注意的是,用for循环读取数据之后,创建的数据集并没有输出到全局环境之后,所以我们需要用assign函数加载到全局环境中去。结果如图,可以看到RAE里面的数据现在都被加载到R studio里面去了,我们可以直接像SAS那样点开数据集,就能查看数据了。

image.png
image.png

可以看到,写了一个循环之后,相比一个一个数据集加载方便多了。现在有了数据,接下来就是对RAW数据集进行处理了,这个之后的文章再讲。

二:读取外部excel数据

我们做项目,有时候数据可能来自外部供应商,比如血药浓度数据,细胞因子那些,所以我们还需要知道如何用R读取excel数据。在SAS中,用一个proc import差不多就可以,在R中,需要用到readxl库。

读取外部excel文件,可能会存在几个需求:

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

  2. 从某一行开始读取

3)日期读取之后变了格式

4)需要将列名重命名成正常变量名

下面一个一个说明,我们也不搞什么花里胡哨的技能,readxl能实现的功能挺多,一个一个去说明太费时间,也打击学习热情,我们有什么需求,就只解决提出需求,其余的 闲得蛋疼的时候可以继续摸索。工作中一般就上面4个需求。

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

library(readxl)
example(read_excel)  #查看read_excel有什么功能及对应的例子

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的时候,你可以用sheet所在的位置,比如程序里面的1代替sheet名,也可以直接指定sheet名称。然后如果不用文件里面的列名,可以通过选项col_names = FALSE实现。

经测试,即使打开了EXCEL文件,R也能正常读取,不像SAS打开excel文件就读取不了了。

image.png
image.png
image.png

R自动将列名重命名为...1 ...2 ....,而且发现最后一列的日期格式读取也错误了

2)从某一行读取,可以通过skip选项,这里我从第二行开始读取

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

发现从第二行开始读取的时候,最后一列的日期格式也展示正确了,可能R是根据第一行的格式来确定这一列展示的格式?第二列日期始终展示正确的原因是因为我设置了这列格式为文本,但是一般外部供应商发过来的数据大多数时候都是不设置格式的。

3)日期读取之后变了格式

解决办法可以像2)一样从某一行开始读取,另一种方法是读取后用as.Date函数处理一下。

需要注意,如果你把列名读取进来的话,在转换的时候会报错,因为第一行“”核查日期”转换不了。会报这个错

“Error in charToDate(x) : 字符串的格式不够标准明确”

我们先看一下只有数字的数据怎么转换,没有中文名称那一行了

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日视为第一天,但实际上它从1899年12月30日开始计数。其实excel日期格式的数据导入到SAS也有一个时间差,也需要特殊处理一下。

如果还需要输出第一行的中文列名,需要注意的是,as.date转换的日期是数值型,但是这列在读取进来的时候是字符型的,所以拼在一起的时候会报上面的错,所以还需要将数值型日期转换成字符型。

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

date_column <- testdata3[[4]]
# 检查日期列的数据类型
if (is.character(date_column)) {
  # 将第二行及其后的数据转换为数字
  date_column_numeric <- as.numeric(date_column[-1])
  
  # 将数字转换为日期格式
  date_column_dates <- as.Date(date_column_numeric, origin = "1899-12-30")
  
  # 将为日期格式转换为字符型
  date_column_dates2<-as.character(date_column_dates)
  # 将转换后的日期放回数据框中
  testdata3[[4]][-1] <- date_column_dates2
  
}
image.png
image.png

4)需要将列名重命名成正常变量名

R中重命名有好几种方式,在SAS中应该只有rename和在data步中创建新变量等于旧变量。

一种是直接使用readxl库重命名

#重命名列名
testdata5 <- read_excel('D:\\R practice\\project\\test.xlsx',sheet="Sheet1",col_names = FALSE)
colnames(testdata5) #查看原始数据集名称

#readxl库
colnames(testdata5) <- c("studyid", "lbdtc", "aval","checkdate")

一种是使用#dplyr库里的rename函数(记得提前加载dplyr到R),这时候前面的变量名是你要rename的名称,跟SAS还不一样。

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

好了,上面就是用R导入数据的几种方式。

祝您中秋愉快!SAS PRO竭诚为您服务!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容