生信R语言:对数据的管理

本文介绍了如何在R中进行数据的基本信息获取、维度和长度计算,以及名称管理、频数计数、数据合并、抽样、计算、字符串处理和缺失值处理等核心操作。通过实例演示了如何使用rbind(), cbind(), merge()和相关函数进行数据操作,适合初学者和数据分析师快速上手。
摘要由CSDN通过智能技术生成

数据基本信息获取

获取数据的基本情况: summary() 函数。
任何 R 对象都可作为summary() 函数的参数,返回对象的统计和概要信息,日常常用且实用的函数。

获取数据维度:dim() 函数
对于高维数据,如矩阵和数据框,dim() 函数可返回对象的维度:行数,列数。

获取数据长度: **length()**函数
用于计算向量、矩阵中元素的个数。
对于一个数据框,length() 则返回列(即变量)的个数。
R 中还有一个计算对象长度的函数:lengths()。注意区分二者:
lengths() 计算的是 R对象中基本元素的长度;s
length() 计算的是 R 对象的长度。
例如我们对一个数据框 df 使用 lengths() 和 length():

L3 <- LETTERS[1:3]
fac <- sample(L3, 5, replace = TRUE)
x <- 1
y <- 1:5
df <- data.frame(x, y, fac)
df
  ## x y fac
## 1 1 1 C
## 2 1 2 C
## 3 1 3 A
## 4 1 4 B
## 5 1 5 C

dim(df) #得结果列表几行几列
## [1] 5 3
length(df) #对象的长度,即x,y,fac
## [1] 3
lengths(df) #基本元素的长度,几个对象的长度
## x y fac
## 5 5 5

获取名称 😗*names()**函数
函数 names() 用于返回 R 对象的名字(如果存在)。上例中的数据框df 的 names 的返回结果为一个 字符向量

names(df)
## [1] "x" "y" "fac"

与名称相关的函数还有几个语意直接的函数:
dimnames() 以列表的形式返回行列名称;
colnames() 返回列名称,rownames() 返回行名称;
其中row.names() 与 rownames() 相似。

获取计数(频数):tabulate() 函数
tabulate() 函数将输入向量整数化后,计算每个整数的出现频数:
c(-2,0,2,3,3,5)是个向量,tabulate(c(-2,0,2,3,3,5))对向量(正)整数化

tabulate(c(-2,0,2,3,3,5)) #-2和0忽略出现0次,从1开始,2一次,3两次
## [1] 0 1 2 0 1

tabulate(c(-2,0,2,3,3,5), nbins=10) #nbins设定计算范围
## [1] 0 1 2 0 1 0 0 0 0 0

上例中 −2 和 0 被忽略,然后计算从 1 开始计算每个整数出现的次数。
nbins设定计算范围:nbins 参数默认时,计算到向量中最大的整数值,而当 nbins=10 时,则计算到 10。

获取元素频度函数:table() 函数,注意区分与tabulate()
table不考虑是否为数字,所以是直接记数,无需考虑正负
table() 函数可用于计算每个元素的频度其效果相当于将向量因子化
后用 summary() 函数分析的结果:

注:factor(c(‘a’,‘b’,‘c’,‘b’))就是将向量因子化(将元素类型归类),再summary求合
注:当我们为 table() 提供两个对象,结果则返回一个。如小例3

table(c('a','b','c','b'))  #效果同下
##
## a b c
## 1 2 1
summary(factor(c('a','b','c','b')))  #效果同上
## a b c
## 1 2 1
table(c('a','b','c','b'), c('a','b','c','b'))
##
  ## a b c
## a 1 0 0
## b 0 2 0
## c 0 0 1

数据合并

数据分析实践中,有需要将两个数据对象合并成一个对象来加以处理。
例如两个数据框中的部分数据列合并为一个新的数据框。
R为我们提供了两种合并数据的思路和相应的函数工具,

  • 一是直接合并数据,
  • 二是通过共同变量合并数据。

第二种方式要求,分布于两处的数据中,至少有一个变量是两处共享的,也就是需要相同变量进行连接,很好理解。

  • 行合并: rbind()函数
    函数 rbind() 可实现数据按行合并:
mat1 <- matrix(rep(1,9),nrow=3)	#rep????一弄了九个
mat1
	## [,1] [,2] [,3]
## [1,] 1 	1 	1
## [2,] 1 	1 	1
## [3,] 1 	1 	1
mat2 <- rbind(mat1,c(2,2,2))  #将mat1和c(2,2,2)行合并
mat2
## [,1] [,2] [,3]
## [1,] 1 1 1
## [2,] 1 1 1
## [3,] 1 1 1
## [4,] 2 2 2


m <- rbind(1, 1:5)  #第一行默认自动补齐1。1:5就是一到五
m
	## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 	1 	 1 	  1 	1
## [2,] 1 	2 	 3 	  4 	5

上小例3中当我们合并两个长度不一致的向量时,R 会按照长向量的长度自动补齐短向量。但需要注意的是,长向量的长度须是短向量长度的 整数倍,否则系统会发出警告,虽有警告但短向量仍会循环补齐

m <- rbind(1:3, 1:5)
## Warning in rbind(1:3, 1:5): number of columns of result is not amultiple
## of vector length (arg 1)
m 	#虽警告但仍自动补齐了
	## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 	2 	 3 	  1		2
## [2,] 1 	2 	 3 	  4		5
  • 列合并:cbind()函数
    函数 cbind() 与 rbind() 操作上类似的,实现按照列合并数据,相当于给数据框添加新的变量
df2 <- cbind(df,z=c(1:10 + 0.1))
df2
  ## x y fac z
## 1 1 1 C 1.1
## 2 1 2 C 2.1
## 3 1 3 A 3.1
## 4 1 4 B 4.1
## 5 1 5 C 5.1
## 6 1 1 C 6.1
## 7 1 2 C 7.1
## 8 1 3 A 8.1
## 9 1 4 B 9.1
## 10 1 5 C 10.1
  • 通过共同变量合并数据:merge()函数
    函数 merge() 允许我们按照两数据集合中共有的部分(变量)合并数据,为了演示 merge 的功能,我们先创建两个数据框
x <- data.frame(k1 = c(NA,NA,3,4,5), k2 = c(1,NA,NA,4,5),
data = 1:5)
x
## k1 k2 data
## 1 NA 1 1
## 2 NA NA 2
## 3 3 NA 3
## 4 4 4 4
## 5 5 5 5
y <- data.frame(k1 = c(NA,2,NA,4,5), k2 = c(NA,NA,3,4,5),
data = 1:5)
y
## k1 k2 data
## 1 NA NA 1
## 2 2 NA 2
## 3 NA 3 3
## 4 4 4 4
## 5 5 5 5

此时创建的两个数据框中含有共同的数据列 data,则可以合并。
除了共有的变量 data,其它变量会按照数据框来源加上后缀以示不同。

merge(x, y, by = "data")

#  data k1.x k2.x k1.y k2.y
1    1   NA    1   NA   NA
2    2   NA   NA    2   NA
3    3    3   NA   NA    3
4    4    4    4    4    4
5    5    5    5    5    5

如果我们按照不同变量进行合并,其实成了判断,显示如下
只有 k1 列中 x 与 y 数据框中等值的部分进行合并,不等值的则由NA 填补。

merge(x, y, by = "k1")
 # k1 k2.x data.x k2.y data.y
1  4    4      4    4      4
2  5    5      5    5      5
3 NA    1      1   NA      1
4 NA    1      1    3      3
5 NA   NA      2   NA      1
6 NA   NA      2    3      3

数据抽样

选取子集

  • 中括号索引
    前文中所有的选取数据子集的方式都是通过中括号索引的方式。
  • subset 函数
    选取数据子集的另一种方式是使用函数 subset(),它可以分别针对数据框(或矩阵)的行和列进行选择: subset(x, subset, select, …)
    其中参数subset用于设定被选择的行,可以接受判断表达式;参数select用于设定被选择的列,下面示例:
df2
  ## x y fac z
## 1 1 1 C 1.1
## 2 1 2 C 2.1
## 3 1 3 A 3.1
## 4 1 4 B 4.1
## 5 1 5 C 5.1
## 6 1 1 C 6.1
## 7 1 2 C 7.1
## 8 1 3 A 8.1
## 9 1 4 B 9.1
## 10 1 5 C 10.1
subset(df2, y > 2)
  ## x y fac z
## 3 1 3 A 3.1
## 4 1 4 B 4.1
## 5 1 5 C 5.1
## 8 1 3 A 8.1
## 9 1 4 B 9.1
## 10 1 5 C 10.1
subset(df2, (y < 9 & z > 3.1), select=c('y','fac','z'))
  ## y fac z
## 4 4 B 4.1
## 5 5 C 5.1
## 6 1 C 6.1
## 7 2 C 7.1
## 8 3 A 8.1
## 9 4 B 9.1
## 10 5 C 10.1

随机抽样sample()
随机抽取数据集合中的部分数据,往往是统计建模中常遇到的情况。R中最简单的方法是使用函数 sample()

sample(x, size, replace = F, prob = NULL, ...)

参数size是定义了多少个数据从集合 x 中抽取出来。
需要说明的是,对于矩阵的子集是按照元素为单位选取size个元素的,而对数据框是按照列为单位选取size个列的。如果我们想按照列选取,则需要下例所写。
参数replace决定了子集的选取是否重置,
当replace=T时,即子集选取后会被重新放入原数据集合中(也就是统计学中常说的有放回的抽样方法,因此新的数据集合中可能出现重复的元素);
当replace=F时,即子集选取后不会被从新放入原数据集合中,那么如果原数据集合中的元素都是唯一的,就不会在新的数据集合中出现重复的元素。

sample(1:10, size=5, replace = F)
## [1] 1 6 2 9 3
sample(1:10, size=5, replace = T)
## [1] 7 6 1 5 8

参数prob接受一个向量,其中每个元素值为集合 x 中元素的抽取概率,
所以概率向量的长度于集合 x 的长度(抽取单位的个数)一致,且和为 1。
上文中提到,如果要针对数据框的行进行抽样,我们可以首先生成一个
由随机抽取的行号组成的向量,然后利用这一向量通过中括号索引的方式来
达到随机按行抽样的目的:????????????不太会这里

randomRowN <- sample(1:nrow(df2),5)df2[randomRowN,]
  ## x y fac z
## 8 1 3 A 8.1
## 9 1 4 B 9.1
## 2 1 2 C 2.1
## 10 1 5 C 10.1
## 7 1 2 C 7.1

数据计算

数学计算
三角函数:sin(), cos(), tan(), asin(), acos(), atan(), atan2()。
对数与指数函数:log(), log10(), exp(), abs(),sqrt(),prod()
ceiling(),floor(),trunc(),round(),signif(), integrate()
统计计算
max(),min(),range()
sum(),mean(),median(),sd(),var(),quantile(),IQR()
diff()
scale()
概率计算
概率密度函数 dnorm()
概率分布函数 pnorm()
分位数函数 qnorm()
随机数生成函数 rnorm()

字符串处理

数据分析实践中需要对字符串进行操作的情况,R 提供了一些函数:
nchar() 计算字符串的长度;
toupper() 转换为大写;
tolower() 转换为小写;
substr(start,stop) 提取字符串的子集,参数start和stop分别定义了子字符串的提取起始和结束位置:

substr("abcdef", start = 2, stop = 4)
## [1] "bcd"

strplit() 分隔字符串为向量,返回的类型为列表,除了要分隔的字符串之外,参数split也是必须的:

strsplit("abcdef", split="c")
## [[1]]
## [1] "ab" "def"
strsplit("abcdef", split="")
## [[1]]
## [1] "a" "b" "c" "d" "e" "f"

paste() 连接字符串,其中连接符号由参数sep定义(默认为空格)

paste("A", "B", sep="-")
## [1] "A-B"
strsplit("A", "B", split="")
## [[1]]
## [1] "A"
paste(1:12, c("st", "nd", "rd", rep("th", 9)), sep ="")
## [1] "1st" "2nd" "3rd" "4th" "5th" "6th" "7th" "8th" "9th" "10th"
## [11] "11th" "12th"

R 中还提供了 有关正则表达式操作的函数:
grep()用于模式匹配;
sub() 用于模式匹配并进行替换。

数据修整

创建变量或重赋值
实践中需要在数据框中创建新的变量,或对已有变量重新赋值,可通过赋值表达式来实现:

变量名 <- 表达式

以上语句中的” 表达式 “可以包含多种运算符和函数。假如现有一个数
据框,我们需要添加两个变量到数据框中用于储存已存在的两个变量的 ‘和’
与 ‘均值’。那么首先我们可以计算出他们的 ‘和’ 与 ‘均值’,并赋值给一个新
的变量:

sumx <- df2$x + df2$y
meanx <- (df2$x + df2$y) / 2

然后利用数据合并的方法 cbind() 来将新的变量添加到原数据框中:

df2 <- cbind(df2,sumx,meanx)

虽然上述方法实现了目的,但并不推荐,还可以这样操作更为简单,且容易理解做:

df2$sumx <- df2$x + df2$y
df2$meanx <- ( df2$x + df2$y ) /2

其实 R 还为我们提供了一个更简单的方法,需要借助函数 transform():

df2 <- transform(df2, sumx = x + y,
meanx = (x + y) / 2)

变量重编码
变量重编码与新变量创建是类似的,只不过在某些时候重编码具有特殊
意义,因此我们单独拿出来讨。有哪些时候需要重编码呢?
• 将一个连续型变量变为离散型的类别变量;
• 为数据进行分组;
• 替换错误编码的数据。
其实前两种情况可以归为一类。如果说新建变量是我们多数用算术运
算符的话,那么重编码往往需要逻辑运算符。首先我们来看第一种情况,R
的全局环境中有一个名叫 women 的数据框,记录 15 个女性的身高与体重
数据,如果我们想根据体重将她们分为三组,我们可以如此操作:

women$physique[women$weight >= 150] <- "fat"
women$physique[women$weight <= 130] <- "lean"
women$physique[women$weight > 130 & women$weight < 150] <- "normal"
women
## height weight physique
## 1 58 115 lean
## 2 59 117 lean
## 3 60 120 lean
## 4 61 123 lean
## 5 62 126 lean
## 6 63 129 lean
## 7 64 132 normal
## 8 65 135 normal
## 9 66 139 normal
## 10 67 142 normal
## 11 68 146 normal
## 12 69 150 fat
## 13 70 154 fat
## 14 71 159 fat
## 15 72 164 fat

为了方面后续分析,我们可以将变量 physique 变为因子类型:

women$physique <- as.factor(women$physique)

上述操作还可以写成更简单的方式:

women <- within(women, {
physique <- NA;
physique[weight >= 150] <- "fat";
physique[weight < 150 & weight > 130] <- "normal";
physique[weight <= 130] <- "lean";})

变量重命名
对某个变量名称需要修改,交互式或者编程方式进行修改。
交互式的可以使用 fix(),调用一个交互式的编辑器,单击变量名然后重命名。
编程式的修改我们可以通过获取变量名称后重新赋值的方式:

names(women)
## [1] "height" "weight" "physique"
names(women)[3] <- 'body'
names(women)
## [1] "height" "weight" "body"

PS:reshape 包还提供了一个 rename() 函数。
操作数据对象的元素
在对数据计算、操作的过程中,经常会对一系列的对象(或者一个复合对象的所有元素)进行同一个操作,并返回一个新的对象。
那同一个操作一般都会由某个函数执行。
R 提供了一系列的函数可以完成这个功能。

apply() 可以对一个矩阵、数据框、数组的每一部分运行同一个函数:

x <- 1:16
dim(x) <- c(4,4)
x
## [,1] [,2] [,3] [,4]
## [1,] 1 5 9 13
## [2,] 2 6 10 14
## [3,] 3 7 11 15
## [4,] 4 8 12 16
apply(x, MARGIN = 1, FUN = sum)
## [1] 28 32 36 40
apply(x, MARGIN = 2, FUN = sum)
## [1] 10 26 42 58

参数MARGIN= 1 时,对行操作;参数MARGIN= 2 时,列操作;
依次类推如果数据对象的维度 = 3 时,那么MARGIN= 3 就可对第三维进行作;而参数FUN定义了操作函数。
apply() 函数操作的数据对象必须具有维度信息,即 dim(X) 不等于
Null,那么对向量和列表这类没有维度信息的数据对象只能换用函数lapply():

lapply(1:3,FUN = function(x) x^2)
## [[1]]
## [1] 1
##
## [[2]]
## [1] 4
##
## [[3]]
## [1] 9

注意其结果以列表的形式给出,如果想要结果以向量、矩阵或数组的形式,则使用sapply() 函数:

sapply(1:3,FUN = function(x) x^2)
## [1] 1 4 9

缺失值处理

数据排序
数据排序常用的数据操作,对向量、矩阵、数组可以使用 sort() 函数进行排序,参数decreasing控制了排序的方式:降序或者升序
与数据框的随机抽取数据类似,数据框排序稍显麻烦,需要借助另一个函数 order():

w1 <- women[sample(1:nrow(women)),]
w1
## height weight body
## 13 70 154 fat
## 2 59 117 lean
## 5 62 126 lean
## 7 64 132 normal
## 6 63 129 lean
## 1 58 115 lean
## 11 68 146 normal
## 15 72 164 fat
## 14 71 159 fat
## 8 65 135 normal
## 3 60 120 lean
## 9 66 139 normal
## 12 69 150 fat
## 4 61 123 lean
## 10 67 142 normal
order(w1$weight)
## [1] 6 2 11 14 3 5 4 10 12 15 7 13 1 9 8
w1[order(w1$weight),]
## height weight body
## 1 58 115 lean
## 2 59 117 lean
## 3 60 120 lean
## 4 61 123 lean
## 5 62 126 lean
## 6 63 129 lean
## 7 64 132 normal
## 8 65 135 normal
## 9 66 139 normal
## 10 67 142 normal
## 11 68 146 normal
## 12 69 150 fat
## 13 70 154 fat
## 14 71 159 fat
## 15 72 164 fat

order() 函数的数据结果需要这样理解:w1 中第 15 个元素需要换到
第 1 个位置上;第 1 个元素需要换到第 2 个位置上;第 12 个元素需要换
到第 3 个位置上;依次类推即可完成按 weight 排序的效果。
如果数据框需要按照两个变量先后排序,那么只需要将第二个变量也同时传递给函数order() 即可

w1[order(w1$weight,w1$height),]
## height weight body
## 1 58 115 lean
## 2 59 117 lean
## 3 60 120 lean
## 4 61 123 lean
## 5 62 126 lean
## 6 63 129 lean
## 7 64 132 normal
## 8 65 135 normal
## 9 66 139 normal
## 10 67 142 normal
## 11 68 146 normal
## 12 69 150 fat
## 13 70 154 fat
## 14 71 159 fat
## 15 72 164 fat

数据重塑形

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值