r

R语言数据处理——Tidyr包

2020-02-16  本文已影响0人  M78_a

参考教程https://4va.github.io/biodatasci/r-tidy.html#review
练习数据下载:https://4va.github.io/biodatasci/data.html

感觉老外写的教程很详细,搭配国内的教程可以更好地学习。本文主要是针对Tidyr包的学习。这个包还是很有用的。

1 先来明白什么是Tidy data数据

Tidy data数据集有两个关键属性。
每一列都是一个变量。
每一行都是一个观察值。

2 看看untidy的数据长啥样

library(readr)
hr <- read_csv("heartrate2dose.csv")
hr
image.png

这个数据的基本内容:
五个不同的name病人(Jon, Ann, Bill, Kate和Joe)服用三种不同的drug药物(A, B, C),两种dose剂量(10和20),测量他们的heart rate心率的数据。

本次数据中有4个变量,name,drug,dose,heart rate。
drug和dose这两个变量绑在了一起。heart rate数据分散在整个列表。对于后续的操作是非常不利的。
例如:我们想通过某些条件过滤数据,使用 filter函数过滤 drug=="a" or dose==20 or heartrate>=80,我们无法操作,因为这些变量的数据不是在某一列中。

3 tidyr package

这个包中主要有两个函数 separate() and gather().
可以使用?separate() ,?gather()查看帮助文档。

gather()函数的作用是:操作多个列,并这些列gather成键-值对的形式。这使得“宽”数据变得更长。

separate()函数的作用是:将一个列分成多个列

首次使用需要安装和下载包:

install.packages("tidyr")
library(tidyr)

4 实战,处理数据

drug/dose 绑在一块,heart rate数据分散在列表。我们分两次操作

4.1,先将drug和dose对应的heart rate对应的多个列数据,用gather命令生成key-value的形式。

gather(hr,key=drugdose,value=hr,a_10, a_20, b_10, b_20, c_10, c_20)

hr %>% gather(key=drugdose, value=hr, a_10, a_20, b_10, b_20, c_10, c_20)
#%>%是R语言中的管道符,相当于Linux中的管道符。将hr数据框传递给后面的函数

第一个参数是要进行变形的数据。
接下来的两个参数是要创建的键和值列的名称,后面的所有相关参数都是我们想要聚集在一起的列

也可以简化操作
hr %>% gather(key=drugdose, value=hr, a_10:c_20)
用一个冒号表示a-10到c-20的所有列

也可以用一个-直接排除我们不想gather的列
hr %>% gather(key=drugdose, value=hr, -name)

这步操作后,实际效果如下:


image.png

可以清楚看到,生成新的两列。原来分散的hr变成了长数据。
但是,还有一个问题未解决,drug和dose这两个变量纠缠一起。下面,我们要用separate()函数给分开。

4.2 separate() 函数

hr %>% 
  gather(key=drugdose, value=hr, -name) %>% 
  separate(drugdose, into=c("drug", "dose"), sep="_")

drugdose是要分割列,into内包含要分割成的两列。sep是分割符号,也就是按照“_”对drugdose的数据进行分割。sep的参数也可以是一个数字,指示要分割的位置。
效果如下


image.png

可以清楚看到每列是一个变量,每行是一个观测值。这就是我们要的tidy数据。

4.3 最后使用管道符连接起来,并且赋给一个新的变量hrtidy

hrtidy <- hr %>% 
  gather(key=drugdose, value=hr, -name) %>% 
  separate(drugdose, into=c("drug", "dose"), sep="_")

4.4 可以使用其他函数进行分析了

# filter
hrtidy %>% filter(drug=="a")
hrtidy %>% filter(dose==20)
hrtidy %>% filter(hr>=80)

# analyze
hrtidy %>%
  filter(name!="joe") %>% 
  group_by(drug, dose) %>%
  summarize(meanhr=mean(hr)
上一篇 下一篇

猜你喜欢

热点阅读