R数据管理
《R语言实战》第4章和第5章
第4章 基本数据管理
#1 基本数据管理####
manager<-c(1,2,3,4,5)
date<-c('10/24/14','10/28/14','10/01/14','10/12/14','05/01/14')
country<-c('US','US','UK','UK','UK')
gender<-c('M','F','F','M','F')
age<-c(32,45,25,39,99)
q1<-c(5,3,3,3,2)
q2<-c(4,5,5,3,2)
q3<-c(5,2,5,4,1)
q4<-c(5,5,5,NA,2)
q5<-c(5,5,2,NA,1)
leadership<-data.frame(manager,date,
country,gender,age,
q1,q2,q3,q4,q5,
stringsAsFactors =F )
1.1 变量管理
1.1.1创建新变量
#写法1:transform创建新变量并保存到数据框中(添加新列并保存到数据框)
leadership<-transform(leadership,mean_age=mean(leadership$age))
#写法2:直接创建
leadership$mean_age<-mean(leadership$age)
1.1.2变量重新编码
#根据年龄重编码新增agecat字段
leadership$agecat[leadership$age>75]<-"elder"
leadership$agecat[leadership$age>=55&leadership$age<=75]<-"middle aged"
leadership$agecat[leadership$age<75]<-"young"
#写法2
#within()函数可修改数据框,顺便添加新变量
leadership<-within(leadership,{
agecat<-NA
agecat[age>75]<-'elder'
agecat[age>=55&age<=75]<-'middle aged'
agecat[age<55]<-'young'
})
1.1.3修改变量名和变量类型(适合数据量比较少的时候)
fix(leadership) #调用交互式编辑器
1.1.4缺失值
#检测缺失值
is.na(leadership[,6:10])
#移除缺失值使用剩余值计算
leadership<-sum(leadership$age,na.rm=TRUE)
#删除含有缺失数据的行(慎用)
newdata<-na.omit(leadership)
newdata
#重编码某些值为缺失值
leadership$age[leadership$age==99]<-NA #年龄为99岁重编码为缺失值
1.1.5 日期转换
#指定格式转换日期变量
#函数as.Date(x,format)默认格式yyyy-mm-dd,可指定format
leadership$date<-as.Date(leadership$date,'%m/%d/%y')
#处理时间函数 p76
Sys.Date() #当天日期
date() #当前的日期和时
dob<-as.Date('1995-05-09')
format(dob,format='%m/%d/%y') #输出指定格式日期值
#计算时间间隔,units参数默认以天days表示
difftime(Sys.Date(),dob,units = 'weeks')
1.1.6 将日期转换为字符型变量
date<-as.character(dates)
1.1.7数据排序
attach(leadership)
newdata<-leadership[order(gender,-age),] #按性别和年龄降序
detach(leadership)
newdata
1.2 数据集的合并
#向数据框添加列,合并两个数据框,类似于inner join使用by参数
total<-merge(dataframeA,dataframeB,by='ID') #相当于内连接
total<-cbind(A,B) #横向合并,每个对象必须拥有相同的行数以及相同的顺序排序
#向数据框添加行,纵向合并,列数相同 p80
#纵向合并要求两个数据框具有相同的变量,不过顺序不必一定相同。
#如果两个数据框变量数不同,做一下变量筛选
total<-rbind(dataframeA,dataframeB)
1.3数据集取子集
1.3.1选入变量
myvars<-c('q1','q2','q3')
newdata<-leadership[myvars]
1.3.2剔除变量
#剔除变量法1
newdata<-leadership[c(-8,-9)] #剔除第8个和第9个变量
#剔除变量法2
myvars<-names(leadership) %in% c('q3','q4') #返回逻辑值
newdata<-leadership[!myvars] #剔除q3,q4变量
1.3.3选入观测
#选入观测法1
newdata<-leadership[leadership$gender=='M' &
leadership$age>30,] #选择30岁以上的男性
#选入观测法2
attach(leadership)
newdata<-leadership[gender=='M' & age>30,]
detach(leadership)
#选入观测法3
newdata<-leadership[1:3,] #选择1-3行的所有列
#限定时间区间提取子集
attach(leadership)
date<-as.Date(date,'%m/%d/%y')
startdate<-as.Date('2014-01-01')
enddate<-as.Date('2014-10-02')
newdata<-leadership[date>=startdate & date<=enddate,]
detach(leadership)
#前面采集子集方法比较笨
#使用subset()函数选择变量和观测(推荐)
newdata<-subset(leadership,age>=35|age<=24,select=c(q1,q2,q3,q4))
newdata<-subset(leadership,age>=35|age<=24,select=c(gebder:q4))
#随机抽样
mysample<-leadership[sample(1:nrow(leadership),3,replace=F),]
1.4 sql操作数据框(sqldf包)
library(sqldf)
newdf<-sqldf("select * from mtcars where carb=1 order by mpg",
row.names=T #使用原始数据框的行名
)
error?
--------------------------------------------------------------------------------------
第5章 高级数据管理
5.1 基本函数
数学函数
abs(-4) #绝对值
sqrt(35) #平方根
ceiling(4.1) #向上取整
floor(3.3) #向下取整
round(x,digits = n) #将x四舍五入指定位小数
统计函数
a<-c(12,13,67,-666,88)
sum(a) #求和
max(a) #最大值
min(a) #最小值
mean(a) #平均数
leanth(a) #求个数
median(a) #中位数
range(a) #分别求最大值和最小值
var(a) #方差
sd(a) #标准差
prod(a) #求向量元素值连乘积
cumsum(a) #累加和向量函数(每一项的值是该项与前一项累加后的值)
summary(a) #该函数会区别对待各个变量,显示连续型变量的最小值、
#最大值、均值、各四分位数;显示类别变量的各水平的频数统计
fivenum(a) #依次返回最小值、下四分位数、中位数、上四分位数、最大值
diff(a,lag = n) #滞后差分,lag指定滞后几项,默认1
scale(x,center = T,scale = T) #将数据对象x按列进行中心化(center=T)
#或标准化(center = T,scale = T),默认均为T
quantile(a,percent) #求分位数
quantile(a,c(0.2,0.4,0.6,0.8))
概率函数
dnorm() #密度函数
pnorm() #分布函数
qnorm() #分位数函数
rnorm() #生成随机数
字符处理函数 p93
a<-c(12,13,67,-666,88)
nchar(a) #计算a中字符数量
nchar(a[3])
b<-'abcd'
substr(b,2,4) #截取字符向量中的字串,用法同mysql
substr(b,2,4)<-'xx' #将截取部分替换
#grep在x中搜索某种模式,函数返回值为位置下标
grep(pattern,x,
ignore.case = F, #默认F区分大小写
fixed=F) #若fixed为F,则pattern为一个正则表达式;
#若fixed为T,则pattern为一个文本字符串
grep('A',c('b','A'),fixed=T)
#sub在x中搜索pattern并以文本replacement替换
sub(pattern,replacement,x,
ignore.case = F,fixed=F )#同上
sub('\\s','.','HELLO WORLD')
#指定字符分割向量中的元素
strsplit(x,split, #split是分隔符
fixed = F)
strsplit('abc','')
#连接字符串,sep默认空格
paste(...,sep="" )
paste('ab',1:3,sep="")
paste('ab',1)
toupper(b) #大写转换
tolower(b) #小写转换
其他函数
str(a) #显示某个对象的结构
length(a) #对象a的长度
seq(from,to,by) #生成一个序列
#将连续变量x分割成n个水平的因子
cut(a,n,ordered_result = F) #ordered_result返回有序因子
pretty(x,n) #创建完美分割点。将连续型变量x分割为n个区间,绘图指定坐标常用
pretty(c(-3,3),30)
5.2 函数应用
#比如需要求每行或每列的均值
apply
apply(X = ,MARGIN=,FUN = ) #x是数据对象,FUN是任意函数,
#矩阵或数据框中,MARING=1表示行,2表示列
mydata<-matrix(rnorm(30),nr=5)
apply(mydata,1,mean)
sapply()
sapply(x,FUN,options) #x是数据框或矩阵,FUN为任意函数
#案例1:将学生各科考试成绩组合成单一成绩指标,并按A-F给出评分
options(digits = 2) #限定输出小数点后数字位数
Student<-c("John Davis","Angela Williams","Bullwinkle Moose","David Jones",
"Janice Markhammer","Cheryl Cushing","Reuven Ytzrhak","Greg Knox",
"Joel England","Mary Rayburn")
Math<-c(502,600,412,358,495,512,410,625,573,522)
Science<-c(95,99,80,82,75,85,80,95,89,86)
English<-c(25,22,18,15,20,28,15,30,27,18)
roster<-data.frame(Student,Math,Science,English,
stringsAsFactors = FALSE)
#对指定列进行均值为0,标准差为1的标准化。因为不同科目份数分值不同,无法比较
z<-scale(roster[,2:4])
score<-apply(z,1,mean) #将均值函数应用于数据框(行维度)
roster<-cbind(roster,score) #将均值添加到数据框中,cbind必须行数相同,添加新列score
y<-quantile(roster$score,c(0.8,0.6,0.4,0.2)) #综合得分的百分位数
#百分位数排名重编码为新的类别型成绩变量
roster$grade[score >= y[1]]<- 'A'
roster$grade[score >= y[2] & score<y[1]]<- 'B'
roster$grade[score >= y[3] & score<y[2]]<- 'C'
roster$grade[score >= y[4] & score<y[3]]<- 'D'
roster$grade[score < y[4]]<- 'F'
name<-strsplit(roster$Student,' ')
#'['是一个可以提取某个对象一部分的函数
firstname<-sapply(name,'[',1)
lastname<-sapply(name,'[',2)
roster<-cbind(firstname,lastname,roster[,-1 #roster[,-1]排除第1列
roster[order(firstname,lastname),] #依姓氏和名字进行排序
roster
5.3 R控制流
#p101
#5.3.1重复和循环for结构
for (var in seq) statement #for重复执行某个语句,直到某个变量的值不再包含在序列seq中为止
a<-c(1:10)
for (i in a) {print('Hello')} #print规范print('x') or {print('x')},花括号中使用分号间隔一组语句
#5.3.2重复和循环while结构
while (cond) statement #重复循环执行一个语句,直到条件不为真为止
i<-10
while (i>0) {print('Hello');i<-i-1}
#5.3.3条件执行
#if-else 满足某个给定条件为真时执行语句,注意条件必须有外括号即if ()
if (cond) statement1 else statement2
a<-9
b<-7
#if (a>b) 'yes' else 'no'
if (a>b) {print('yes')} else {print('no')} #规范点的写法
#ifelse结构 是if-else结构比较紧凑的向量化版本
ifelse (cond statement1 statement2)
a<-9
b<-7
#ifelse (a>b,'yes','no')
ifelse (a>b,print('yes'),print('no')) #为什么返回两个?
#5.3.4 switch结构 根据一个表达式的值选择语句执行 适合多条件
feel<-c('sad','happy')
for (i in feel) {
print (
switch(i,
sad='no no no',
happy='yes yes',
angry='calm down'))}
5.4用户自编写函数P103
myfunction<-function(arg1,arg2,...) {
statument
return(object)
}
5.5 数据整合与重构p105
5.5.1转置矩阵或数据框
t(data.frame) #行列转置
5.5.2aggregate整合数据
aggregate(x,by,FUN) #x是待折叠对象,by是一个变量名组成的列表(用于分组),FUN是用来计算描述性统计量的标量函数
#举例:按cyl、year分组统计均值
options(digits = 3) #设置小数位数
attach(mtcars)
aggdata<-aggregate(mtcars,
by=list(group.cyl=cyl, group.gears=gear),#分组列重命名
FUN=mean,na.rm=T)
5.5.3 reshape2包-重构和整合数据
install.packages("reshape2")
library("reshape2", lib.loc="D:/R/R-3.6.0/library")
#数据融合(melt) p106
#把数据从宽变长,类似于列转行,数据列包含主键id+变量+值
ID<-c(1,1,2,2)
Time<-c(1,2,1,2)
X1<-c(5,3,6,2)
X2<-c(6,5,1,4)
mydata<-data.frame(ID,Time,X1,X2)
5.5.3.1数据集融合(melt)-指定唯一确定每个测量所需的变量(保留的列名)
md<-melt(mydata,id.vars =c('ID','Time')) #程序会自动选择度量变量
md<-melt(mydata,id =c('ID','Time')) #两种写法均可
#可以重命名度量列和值列
md<-melt(mydata,
id.vars = c('ID','Time'), #标识变量,即类似主键
variable.name = "X2", #重命名度量列
value.name = "count" #重命名值列
)
#直接重塑,不指定保留列
set.seed(1234 #设置种子,让结果可重现
fit<-kmeans(iris[1:4],3)
means<-fit$centers
dfm<-melt(means) #重塑成长格式(列转行),每行都有唯一标识id
5.5.3.2数据集重铸(dcast)
#把数据从长变宽,类似于行转列
newdata<-dcast(md,formula,fun.aggregate) #md为已融合数据,formula描述最后想要结果,
#fun.aggregate(可选)是数据整合函数,可选的.其接受形式
#row1+row2+...~colvar1+colvar2+...
#dcast()函数要求指明标识变量(留下来的列)和可变变量(转化成新列的变量)
#波浪线(~)左边表示标识变量,右边表示可变变量
md<-melt(mydata,id =c('ID','Time')) #重塑数据
#不执行整合
dcast(md,ID+Time~variable)
dcast(md,ID+variable~Time)
dcast(md,ID~variable+Time)
#执行整合
dcast(md,ID~variable,mean)
dcast(md,Time~variable,mean)
dcast(md,ID~Time,mean)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!