在一般情況下,我們都是在數據分析的需求前提下去選擇使用R語言。而實際上,數據分析里,百分之八十的工作,都是在數據清洗。并不只是我們平時會提到的異常值處理或者是整合格式,更多會涉及到將各種各樣的數據整合,按照要求去除掉不合規的數據,再并到一起形成一個純凈的,可利用的數據,甚至有些時候還需要進行脫敏操作,防止對后續模型訓練之類的影響,下面我來介紹一下經常會用到的操作。
篩選
按行操作
1、一般來講,我們用的最多的就是filter(),無他,簡單易懂,只需要在括號內加上我們的條件就行了,不過要注意用于篩選的條件一般都是要滿足其格式的,建議在寫之前先明確好要用到的東西,而不是一股腦地寫邏輯。當然了,這里我也踩過一個小坑,就是filter()在運行時是不能識別NA的,在篩選時會自動去掉NA那一行,會因此忽略掉很多信息,所以我們一般先對數據集做NA判斷,用is.na(),將NA值返回為1或者0,從而避免過濾了重要的信息。
2、而另一個用的比較多的就是slice()了,一般我們在篩選排名或者時間時用到,比如
lab_base <- lab_base %>%group_by(ID)%>% # 按照ID分組arrange(TIME)%>% # 按照TIME排序 slice(TIME,n=1)%>% # 選取時間最早的數據ungroup()%>%dplyr::select(ID,TIME,VALUE)
代碼的意思是在每一組ID的分組內,先按照時間排序,再篩選時間最早的那個數據保留,這種用法相比平時用mid_time,可以節省很多算力空間,尤其是在涉及到數據量很大的rds文件時,大大提高我們的效率。
按列操作
而select()和mutate(),相信如果接觸過一點R語言的都知道,我們經常會看到這兩個語法,前者是把保存想要的列數據,后者則是對數據進行操作,添加或減少變量,有時也會用來添加中間變量來協助篩選,在結束時再去掉。值得注意的是,有很多包里都有select()的用法,我們一般默認的select()是dplyr里的,如果你不確定是否會調用到其他包的畫,像上文用到的dplyr::select會直接調用我們想要的select。
節省算力小技巧
因子化
很多時候,我們存儲的數據并不只是值,也有可能是文字,其中,有很多時候屬于類別,比如男女,職業等,這個時候其實我們主要的需求是區分,而不是用這個值,自然也希望代碼可以像我們一樣,用起來簡單。這個時候就可以對該列數據因子化,把他轉換為分類變量,相當于把中文轉換成了數字,這樣會更好區分,所用到的內存也會更少。
按類別賦予值
與因子化的核心思想一樣,都是通過節省代碼判斷中文的時間,只不過不同的是,我們可以新建一列,在篩選的同時先賦予一個等同于其類別的數字,方便在后面調用分類的時候用創建的新列,從而節省算力,比如:
lab_base $test_new <- 0
lab_base[grep("醫生|科學家|植物學家",lab_base$NEW_JOB),]$test_new <- 1
這樣,假如我們要篩選高科技人才時,就可以直接篩選test_new值為1的列。
函數
就像我們在其他語言中學過的類似一樣,用function來執行很多需要重復的操作,可以節省算力,并大大提高我們的代碼效率以及對代碼的理解,但與其他語言不同的是,列表下函數的作用對象是會改變的,也就是說在寫邏輯之前,不僅要想邏輯本身是否通順,更要想清楚操作的對象是否適用于該方法,比如列表下的子列表,很多時候我們會將其轉換為dataframe來操作,從而更好地處理數據,但在涉及到用function來操作列表里的內容是,用lapply來操作子列表,也會很方便,也能使其在操作完保持子列表的特性嵌套在列表中。