获取更多R语言和生信知识,请欢迎关注公众号:医学和生信笔记
医学和生信笔记 公众号主要分享:1.医学小知识、肛肠科小知识;2.R语言和Python相关的数据分析、可视化、机器学习等;3.生物信息学学习资料和自己的学习笔记!
文章目录
- R语言缺失值插补之`simputation`包
- 安装R包
- 基本使用方法
- 示例
- 使用管道符连接多种插补方法
- 使用一个固定值进行插补
- 对多列使用同一种插补方法
- 分组插补
- 使用`impute_proxy`指定自己的插补方法
- 使用在其他数据集中训练过的模型插补数据
R语言缺失值插补之simputation
包
R语言中有很多插补缺失值的R包,但是这些R包的使用语法都不一样,不利于学习和记忆。
simputation
包旨在简化缺失值插补的流程,提供了统一的使用语法,提供多种常见的插补缺失值的方法,可以和管道符%>%
连用,非常值得学习。
这个包提供了很多了插补缺失值的方法,很多方法我也没有使用过,今天学习一下。目前支持以下插补方法:
- 基于模型的方法
- 线性回归
- 稳健线性回归
- 岭回归/弹性网络/lasso回归
- CART模型(决策树)
- 随机森林
- 多元插补
- 基于最大期望值的方法
- missForest
- Donor imputation (including various donor pool specifications)
- K最近邻法
- sequential hotdeck (LOCF, NOCB)
- random hotdeck
- Predictive mean matching
- 其他
- median imputation
- Proxy imputation: 使用其他列的值或使用简单的转换得到的值.
- Apply trained models for imputation purposes.
安装R包
#install.packages('simputation')
此包需要很多依赖包,默认不会安装依赖包,可以通过以下代码全部安装:
#install.packages('simputation', dependencies = T)
基本使用方法
impute_<model>(data, formula, [model-specific options])
model
是使用的方法,目前支持以下方法:
-
impute_rlm
: robust linear model -
impute_en
: ridge/elasticnet/lasso -
impute_cart
: CART -
impute_rf
: random forest -
impute_rhd
: random hot deck -
impute_shd
: sequential hot deck -
impute_knn
: k nearest neighbours -
impute_mf
: missForest -
impute_em
: mv-normal -
impute_const
: 用一个固定值插补 -
impute_lm
: linear regression -
impute_pmm
: Hot-deck imputation -
impute_median
: 均值插补 -
impute_proxy
: 自定义公式插补,可以用均值等
data
是需要插补的数据框,输出数据和输入数据结构一样,只不过缺失值被插补了。
formula
指定需要插补的列。
[model-specific options]
是根据所选模型不同有不同的参数。
示例
使用鸢尾花数据集,先把其中的一些值变为缺失值。
dat <- iris
dat[1:3, 1] <- dat[3:7, 2] <- dat[8:10, 5] <- NA
head(dat, 10)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 NA 3.5 1.4 0.2 setosa
## 2 NA 3.0 1.4 0.2 setosa
## 3 NA NA 1.3 0.2 setosa
## 4 4.6 NA 1.5 0.2 setosa
## 5 5.0 NA 1.4 0.2 setosa
## 6 5.4 NA 1.7 0.4 setosa
## 7 4.6 NA 1.4 0.3 setosa
## 8 5.0 3.4 1.5 0.2 <NA>
## 9 4.4 2.9 1.4 0.2 <NA>
## 10 4.9 3.1 1.5 0.1 <NA>
使用线性回归方法插补缺失值:
根据Sepal.Width
和Species
这两列,来预测Sepal.Length
这一列的缺失值:
library(simputation)
da1 <- impute_lm(dat, Sepal.Length ~ Sepal.Width + Species)
head(da1, 10)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.076579 3.5 1.4 0.2 setosa
## 2 4.675654 3.0 1.4 0.2 setosa
## 3 NA NA 1.3 0.2 setosa
## 4 4.600000 NA 1.5 0.2 setosa
## 5 5.000000 NA 1.4 0.2 setosa
## 6 5.400000 NA 1.7 0.4 setosa
## 7 4.600000 NA 1.4 0.3 setosa
## 8 5.000000 3.4 1.5 0.2 <NA>
## 9 4.400000 2.9 1.4 0.2 <NA>
## 10 4.900000 3.1 1.5 0.1 <NA>
此处Sepal.Length
的第3个值还是NA
,这是因为Sepal.Width
这一列的第3个值是NA
导致的,线性回归不能插补这样的缺失值。
可以通过中位数进行插补:
da2 <- impute_median(da1, Sepal.Length ~ Species) # Species用来分组,相当于根据Species这一列分组求中位数然后分别插补
head(da2, 10)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.076579 3.5 1.4 0.2 setosa
## 2 4.675654 3.0 1.4 0.2 setosa
## 3 5.000000 NA 1.3 0.2 setosa
## 4 4.600000 NA 1.5 0.2 setosa
## 5 5.000000 NA 1.4 0.2 setosa
## 6 5.400000 NA 1.7 0.4 setosa
## 7 4.600000 NA 1.4 0.3 setosa
## 8 5.000000 3.4 1.5 0.2 <NA>
## 9 4.400000 2.9 1.4 0.2 <NA>
## 10 4.900000 3.1 1.5 0.1 <NA>
使用决策树方法来插补Species
这一列:
da3 <- impute_cart(da2, Species ~ .)
head(da3,10)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.076579 3.5 1.4 0.2 setosa
## 2 4.675654 3.0 1.4 0.2 setosa
## 3 5.000000 NA 1.3 0.2 setosa
## 4 4.600000 NA 1.5 0.2 setosa
## 5 5.000000 NA 1.4 0.2 setosa
## 6 5.400000 NA 1.7 0.4 setosa
## 7 4.600000 NA 1.4 0.3 setosa
## 8 5.000000 3.4 1.5 0.2 setosa
## 9 4.400000 2.9 1.4 0.2 setosa
## 10 4.900000 3.1 1.5 0.1 setosa
使用管道符连接多种插补方法
使用 %>%
管道符连接一系列操作:
library(magrittr)
da4 <- dat %>%
impute_lm(Sepal.Length ~ Sepal.Width + Species) %>%
impute_median(Sepal.Length ~ Species) %>%
impute_cart(Species ~ .)
head(da4,10)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.076579 3.5 1.4 0.2 setosa
## 2 4.675654 3.0 1.4 0.2 setosa
## 3 5.000000 NA 1.3 0.2 setosa
## 4 4.600000 NA 1.5 0.2 setosa
## 5 5.000000 NA 1.4 0.2 setosa
## 6 5.400000 NA 1.7 0.4 setosa
## 7 4.600000 NA 1.4 0.3 setosa
## 8 5.000000 3.4 1.5 0.2 setosa
## 9 4.400000 2.9 1.4 0.2 setosa
## 10 4.900000 3.1 1.5 0.1 setosa
使用一个固定值进行插补
原数据这样:
head(dat, 10)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 NA 3.5 1.4 0.2 setosa
## 2 NA 3.0 1.4 0.2 setosa
## 3 NA NA 1.3 0.2 setosa
## 4 4.6 NA 1.5 0.2 setosa
## 5 5.0 NA 1.4 0.2 setosa
## 6 5.4 NA 1.7 0.4 setosa
## 7 4.6 NA 1.4 0.3 setosa
## 8 5.0 3.4 1.5 0.2 <NA>
## 9 4.4 2.9 1.4 0.2 <NA>
## 10 4.9 3.1 1.5 0.1 <NA>
使用7插补:
da4 <- impute_const(dat, Sepal.Length ~ 7)
head(da4,10)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 7.0 3.5 1.4 0.2 setosa
## 2 7.0 3.0 1.4 0.2 setosa
## 3 7.0 NA 1.3 0.2 setosa
## 4 4.6 NA 1.5 0.2 setosa
## 5 5.0 NA 1.4 0.2 setosa
## 6 5.4 NA 1.7 0.4 setosa
## 7 4.6 NA 1.4 0.3 setosa
## 8 5.0 3.4 1.5 0.2 <NA>
## 9 4.4 2.9 1.4 0.2 <NA>
## 10 4.9 3.1 1.5 0.1 <NA>
复制另一列的值进行插补:
da4 <- impute_proxy(dat, Sepal.Length ~ Sepal.Width)
head(da4,10)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 3.5 3.5 1.4 0.2 setosa
## 2 3.0 3.0 1.4 0.2 setosa
## 3 NA NA 1.3 0.2 setosa
## 4 4.6 NA 1.5 0.2 setosa
## 5 5.0 NA 1.4 0.2 setosa
## 6 5.4 NA 1.7 0.4 setosa
## 7 4.6 NA 1.4 0.3 setosa
## 8 5.0 3.4 1.5 0.2 <NA>
## 9 4.4 2.9 1.4 0.2 <NA>
## 10 4.9 3.1 1.5 0.1 <NA>
对多列使用同一种插补方法
根据Petal.Length
和Species
这两列使用rlm
方法插补Sepal.Length
和Sepal.Width
:
da5 <- impute_rlm(dat, Sepal.Length + Sepal.Width ~ Petal.Length + Species)
head(da5)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 4.945416 3.500000 1.4 0.2 setosa
## 2 4.945416 3.000000 1.4 0.2 setosa
## 3 4.854056 3.378979 1.3 0.2 setosa
## 4 4.600000 3.440107 1.5 0.2 setosa
## 5 5.000000 3.409543 1.4 0.2 setosa
## 6 5.400000 3.501236 1.7 0.4 setosa
同样也支持tidyverse
中的.
和-
,以下代码使用均值加残差插补除了Species
的所有列:
da6 <- impute_lm(dat, . - Species ~ 0 + Species, add_residual = "normal") # Species用来分组
head(da6)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 4.292233 3.500000 1.4 0.2 setosa
## 2 4.132790 3.000000 1.4 0.2 setosa
## 3 4.443134 3.643322 1.3 0.2 setosa
## 4 4.600000 3.518055 1.5 0.2 setosa
## 5 5.000000 3.355422 1.4 0.2 setosa
## 6 5.400000 3.094199 1.7 0.4 setosa
分组插补
可以在公式中使用|
指定组。
# 新建一个含缺失值的数据框
dat <- iris
dat[1:3,1] <- dat[3:7,2] <- NA
# 根据Species分组,然后再插补
da8 <- impute_lm(dat, Sepal.Length ~ Petal.Width | Species)
head(da8)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 4.968092 3.5 1.4 0.2 setosa
## 2 4.968092 3.0 1.4 0.2 setosa
## 3 4.968092 NA 1.3 0.2 setosa
## 4 4.600000 NA 1.5 0.2 setosa
## 5 5.000000 NA 1.4 0.2 setosa
## 6 5.400000 NA 1.7 0.4 setosa
如果指定了一个或多个分组变量(通过用+分隔多个变量来指定多个),函数内部会进行以下操作:
- 根据分组变量的值将数据划分为子集
- 估计每个数据子集的模型并进行插补
- 组合插补的子集
也可以和dplyr
包的group_by
连用:
library(magrittr)
library(dplyr)
##
## 载入程辑包:'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
dat <- iris
dat[1:3,1] <- dat[3:7,2] <- NA
dat %>% group_by(Species) %>%
impute_lm(Sepal.Length ~ Petal.Width)
## # A tibble: 150 x 5
## # Groups: Species [3]
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## * <dbl> <dbl> <dbl> <dbl> <fct>
## 1 4.96 3.5 1.4 0.2 setosa
## 2 4.96 3 1.4 0.2 setosa
## 3 4.96 NA 1.3 0.2 setosa
## 4 4.6 NA 1.5 0.2 setosa
## 5 5 NA 1.4 0.2 setosa
## 6 5.4 NA 1.7 0.4 setosa
## 7 4.6 NA 1.4 0.3 setosa
## 8 5 3.4 1.5 0.2 setosa
## 9 4.4 2.9 1.4 0.2 setosa
## 10 4.9 3.1 1.5 0.1 setosa
## # ... with 140 more rows
使用impute_proxy
指定自己的插补方法
impute_proxy
允许自定义formula
自定义一个robust ratio imputation
方法进行插补:
dat <- iris
dat[1:3,1] <- dat[3:7,2] <- NA
dat <- impute_proxy(dat, Sepal.Length ~ median(Sepal.Length,na.rm=TRUE)/median(Sepal.Width, na.rm=TRUE) * Sepal.Width | Species)
head(dat)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.147059 3.5 1.4 0.2 setosa
## 2 4.411765 3.0 1.4 0.2 setosa
## 3 NA NA 1.3 0.2 setosa
## 4 4.600000 NA 1.5 0.2 setosa
## 5 5.000000 NA 1.4 0.2 setosa
## 6 5.400000 NA 1.7 0.4 setosa
自定义使用均值进行插补:
dat <- iris
dat[1:3,1] <- dat[3:7,2] <- NA
dat <- impute_proxy(dat, Sepal.Length ~ mean(Sepal.Length,na.rm=TRUE))
head(dat)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.862585 3.5 1.4 0.2 setosa
## 2 5.862585 3.0 1.4 0.2 setosa
## 3 5.862585 NA 1.3 0.2 setosa
## 4 4.600000 NA 1.5 0.2 setosa
## 5 5.000000 NA 1.4 0.2 setosa
## 6 5.400000 NA 1.7 0.4 setosa
自定义使用均值进行插补(先根据Species
分组再计算均值):
dat <- iris
dat[1:3,1] <- dat[3:7,2] <- NA
dat <- impute_proxy(dat, Sepal.Length ~ mean(Sepal.Length,na.rm=TRUE) | Species)
head(dat)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.012766 3.5 1.4 0.2 setosa
## 2 5.012766 3.0 1.4 0.2 setosa
## 3 5.012766 NA 1.3 0.2 setosa
## 4 4.600000 NA 1.5 0.2 setosa
## 5 5.000000 NA 1.4 0.2 setosa
## 6 5.400000 NA 1.7 0.4 setosa
使用在其他数据集中训练过的模型插补数据
在其他数据集训练模型
m <- lm(Sepal.Length ~ Sepal.Width + Species, data = iris)
新建一个要插补的数据集
dat <- iris
dat[1:3,1] <- dat[3:7,2] <- NA
head(dat)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 NA 3.5 1.4 0.2 setosa
## 2 NA 3.0 1.4 0.2 setosa
## 3 NA NA 1.3 0.2 setosa
## 4 4.6 NA 1.5 0.2 setosa
## 5 5.0 NA 1.4 0.2 setosa
## 6 5.4 NA 1.7 0.4 setosa
使用训练过的模型进行插补
dat <- impute(dat, Sepal.Length ~ m)
head(dat)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.063856 3.5 1.4 0.2 setosa
## 2 4.662076 3.0 1.4 0.2 setosa
## 3 NA NA 1.3 0.2 setosa
## 4 4.600000 NA 1.5 0.2 setosa
## 5 5.000000 NA 1.4 0.2 setosa
## 6 5.400000 NA 1.7 0.4 setosa
获取更多R语言和生信知识,请欢迎关注公众号:医学和生信笔记
医学和生信笔记 公众号主要分享:1.医学小知识、肛肠科小知识;2.R语言和Python相关的数据分析、可视化、机器学习等;3.生物信息学学习资料和自己的学习笔记!