R语言-实用功能性语句2

(2017-05-30 银河统计)

  本篇文章对工作中使用的R语言实用语句进行总结,方便查找和复用。

目录概览

1)R语言生成表格html

2)Json格式数据和R格式数据互转

3)[ ]数据的提取

4)which的用法

5)Subset

6)R读取excel数据

7)R设置stringsAsFactors=F问题相关

8)使用R读取json文件并转成data.frame

9)R运行环境初始化

10)R中函数的输出—print、return&list

11)异常值处理——如何报错

12)如何在循环中,实时输出时间消耗

13)“列表”用法小结

14)构造新序列

15)数据框和列表--直接定义变量名

16)names、str、unique组合使用

17)typeof()、mode()、class()组合使用

18)逻辑运算

19)数据合并-merge()函数

20)cbind和rbind函数

21)不等长合并

22)语句22

23)语句23

24)语句24

25)语句25

26)语句26

27)语句27

28)语句28

29)语句29

30)语句30


1)R语言生成表格html

	# oPath <- "D:/" 
	# oName <- "test"   
	# oType <- "csv"
	# oPathFile <- paste(oPath,oName,'.',oType,sep="",collapse="")
	# mydata <- read.csv(oPathFile,header=T)
	
	mydata <- read.table("clipboard",header=T)
	class(mydata)
	dim(mydata)
	head(mydata)
	
	oTBPaste <- function(rowdata, oType){
	  
	  if(oType==1){
	    result <- paste("<td>",rowdata,"</td>",sep="",collapse="")
	  }else if(oType==2){
	    result <- paste("<th>",rowdata,"</th>",sep="",collapse="")
	  }
	  return(result)
	  
	}
	
	oTitle <- names(mydata)
	# length(oTitle)
	oTitle <- paste("<th>",oTitle,"</th>",sep="",collapse="")
	oTB1 <- "<table style='width:100%; font-size:8pt;' border=1>"
	oTB2 <- paste("<tr style='font-weight: bold;text-align:left;font-size:8pt;color:#990000'>",oTitle,"</tr>",sep="",collapse="")
	oTB3 <- apply(mydata, 1, oTBPaste, 1)
	# class(oTB3)
	# length(oTB3)
	oTB4 <- paste("<tr>",oTB3,"</tr>",sep="",collapse="")
	oTB5 <- "</table>"
	oTB <- paste(oTB1,oTB2,oTB4,oTB5,sep="",collapse="")
	
	# oTB
	cat(oTB, "\n")
	
	# oPath <- "C:/Users/abdata/Desktop/" 
	# oName <- "oTB"   
	# oType <- "txt"
	# oPathFile <- paste(oPath,oName,'.',oType,sep="",collapse="")
	# write.csv(oTB,file=oPathFile,row.names=F,quote=F)

2)Json格式数据和R格式数据互转

	library(rjson)
	oJs_str <- '{"oTableName":"data_sf_bc_index_price" , "oFieldType":["number", "text", "number"], "oNum":[1, 0, 1]}'
	oJs <- fromJSON(oJs_str)
	oTableName <- oJs$oTableName
	oFieldType <- oJs$oFieldType
	oNum <- oJs$oNum
	oTableName
	oFieldType
	oNum

3)[ ]数据的提取

	[]    用来提取对象相同的类型,可以包含不止一个元素
	[[]]  用来提取额 list或data frame里面的元素,一般只能提取单个的元素
	$     通过名字来提取 list 或 data frame的元素

4)which的用法

	zz<-c(5,2,-3,8,12,1)
	which(zz*zz>8)
	[1] 1 3 4 5
	
	### which反馈回来的满足要求的索引号
	a[which(a$Ozone>31 & a$Temp>90),]
	a[which(a$Month==6),]
	mydata[which(mydata$gender=='F' & mydata$age > 65), ]
	
	### 重新提取数据的奇数行
	ni[seq(1,nrow(ni),2), ]
	### 判断某个数是否存在
	aa$a <- c(6,1,4,5,5,1)
	if (length(which(aa$a ==100))) print("zzz")
	if (length(which(aa$a ==6)))   print("zzz")
	if (!length(which(aa$a ==6)))  print("zzz")

5)Subset

	subset(mydata, age >= 20 | age < 10,select=c(ID, Weight))
	
	subset(mydata, sex=="m" & age > 25, select=weight:income)
	### 注:& 表示 和, | 表示 或

	mydata[sample(1:nrow(mydata), 50,replace=FALSE),]
	
	library(gcookbook)  # For the data set
	cdat <- subset(countries, Year==2009 & Name %in% c("Canada", "Ireland", "United Kingdom", "United States"))
	c2009 <- subset(countries, Year==2009, select=c(Name, GDP, laborrate, healthexp, infmortality))
	
	### subset筛选与索引筛选的区别
	#### 索引筛选没法区分NA,不知道该不该删去
	> x<-c(6,1:3,NA,12)
	> x
	[1] 6 1 2 3 NA 12
	> x[x>5]
	[1] 6 NA 12
	> subset(x,x>5)
	[1] 6 12

6)R读取excel数据

	# 有时候会遇见Excel文件,使用R语言读取略显麻烦。写个函数即可,代码如下(注意使用了RODBC包):
	
	xlsx_read <- function(fileName) {  
	    require(RODBC)  
	    conn = odbcConnectExcel(fileName)  
	    sheetName <- sqlTables(conn)$TABLE_NAME  
	    data <- list()  
	    for(i in 1 : length(sheetName)) {  
	        data[[i]] = sqlFetch(conn, sheetName[i])  
	    }  
	    close(conn)
	    return(data)  
	}  

	# 获取目录下所有文件名

	filenames=dir("C:/Users/abdata/Desktop/")
	## or推荐第二种
	setwd("C:/Users/abdata/Desktop/")
	filenames=dir()

	# 读取文件输出文件

	require(data.table)
	da<- fread("test_data.csv", header=FALSE)
	u<- read.csv("test_data.csv",fileEncoding='gbk',header = TRUE)   # 读取gbk编码文件
	write.table (out, file ="test_data.csv", sep ="," , row.names=F, col.names=F, quote=F)

	# 读写xlsx文件

	library("xlsx")
	t=read.xlsx('test_data.xlsx',sheetIndex=1)
	write.xlsx(t, file="./s.xlsx")


	# list在批量读取数据时候的用法:

		1、如何循环读取xlsx中的sheet数据,然后批量放入list之中?——先定义list
		2、如何定义写出时候的文件名字——paste函数

	批量读取的基本流程就是:写入(list[[i]])、操作、写出

	#1、读取xlsx中所有的sheet表格  
	# 如果像vector一样定义List??——list()函数来主动定义,用data.list[[i]]来赋值

	data.list<-list()  
	for (i in 1:2){  
	  data.list[[i]]=read.xlsx("C1.xlsx",i)  
	}  
	
	以上是写入,看看如何写出:
	
	# 3、利用List批量读出操作  
	# 难点:如果构造输出表格的名称——paste来构造名称  

	flie=list()  
	xlsxflie=paste(1:2,".xlsx",sep="")  
	  
	for(i in 1:2){  
	flie[[i]]=paste("C:/Users/long/Desktop/",xlsxflie[i],sep="")  
	write.xlsx(data.list2[[i]],file)  
	}  

	写出时候文件名称困扰我很久,如何按照一定的规则来命名,可以先用paste弄好固定格式,然后通过paste[i]循环调用。其中:paste之后会有如vector一般的格式,可以用[i]来调用。

7)R设置stringsAsFactors=F问题相关

	stringsAsFactors=F

	# 以前在r里读数据,经常把character读成factor,还得费半天劲把它转回来,尤其是把factor转成numeric还没有那么直接。例如:

		dat <- read.csv("C:/Users/abdata/Desktop/test_data.csv", header=T, stringsAsFactors = F)

	# 存数据时,经常多出一列id,很讨厌,设置row.names = F,比如:

		write.csv(dat, "C:/Users/abdata/Desktop/test_data.csv", row.names = F)

8)使用R读取json文件并转成data.frame

	library(jsonlite)
	ftag <- "C:/Users/abdata/Desktop/twitter_text_test_period"
	data <- readLines(gzfile(paste0(ftag,"1.json.gz")))
	datalist <- strsplit(data, '\n')
	b <- sapply(datalist, fromJSON)
	indx <- sapply(b, length)
	df <- as.data.frame(do.call(rbind, lapply(b, 'length<-', max(indx))))
	colnames(df) <- names(b[[which.max(indx)]])

9)R运行环境初始化

	options(stringsAsFactors=F, scipen=99)  # scipen 科学计数法相关
	rm(list=ls())
	gc()    # 清空垃圾内存
	getwd() # 获得工作路径信息
	setwd() # 设置工作路径

10)R中函数的输出—print、return&list

如果有很多输出项目,那么需要return(终止运算,并输出return中的项目)最终输出的项目。

R中默认的情况是将最后一句作为返回值。

  • return&list组合

      	sbdeep <- function(data, parts, xiaoz){  
      	  parts<-parts         # 分几个箱  
      	  xiaoz<-xiaoz         # 极小值  
      	  # 这里以data等比分为4段,步长为1/4  
      	  value<-quantile(data,probs = seq(0,1,1/parts))
      	  number<-mapply(function(x){  
      	    for (i in 1:(parts-1))   
      	    {  
      	      if(x>=(value[i]-xiaoz)&x<value[i+1])  
      	      {  
      	        return(i)  
      	      }  
      	    }  
      	    if(x+xiaoz>value[parts])  
      	    {  
      	      return(parts)  
      	    }  
      	    return(-1)  
      	  },data)  
      	  # 打标签L1 L2 L3 L4  
      	  return(list(degree=paste("L",number,sep=""),degreevalue=number,value=table(value),number=table(number)))  
      	  # 将连续变量转化成定序变量,此时为L1,L2,L3,L4...根据parts               
      	}  
    
      return和list的组合输出结果比较合理。
    
      该函数是对单个序列数据进行等深分箱,可以返回四类:
      一个基于L1L2L3....的每个指标标签序列degree;
      标签序列值degreevalue,
      每个百分位数对应的变量值value,
      不同百分点的数量number。
    
  • print直接输出

      function(){  
        print(plot(cv.out))   
      } 
    
      function(){  
        print('hello world')   
      } 
    

11)异常值处理——如何报错

# 异常处理,当仅输入一个数据的时候,告知不能计算标准差  
	if(length(x) == 1){                            
		stop("can not compute sd for one number, a numeric vector required.\n")         
	}

12)如何在循环中,实时输出时间消耗

第一办法:使用Rstudio版本,里面有一个Profiling with profvis,可以很好的对你函数每一步的耗时进行参看。

第二办法:利用difftime函数

	t1 = Sys.time()  
	for (i in 1:5){  
		a=a+1  
		b=a*a  
		print(difftime(Sys.time(), t1, units = 'sec'))  
	}
 
先预设当前时间,然后用difftime+print方式,循环输出。

13)“列表”用法小结

  • 提取某List某指标

    方法一:先编写一个提取list子集的函数:

      subdate<- function(x){
      	x$DATE
      }
    

    然后用lapply或者sapply,sapply(s,subdate)看一下出来的结果

    方法二:提取DATE内容:

      s[[1]]$DATE
    

    变动其中的数字,就可以把每一组的DATE提取出来了。(需要自己编写循环)

    方法三:提取长度大于某程度的list

      x[lapply(x, length)>100]  
    

    用lapply计算每个x的长度。

  • list之间的合并

    list之间的合并用:

      c(list(1),list(2)) 
    

14)构造新序列

  • 1、数值构造函数rep与seq

      # 数值构造rep与seq  
      rep(1:4,each=2)  # 依次重复1:4两遍  
      rep(1:4,2)       # 注意,重复1:4两遍  
      seq(from=3,to=5,by=0.2)
      rep(seq(from=3,to=5,by=0.2),2) # 混合使用  
    

    rep在使用过程中也很灵活,each代表AABB;默认的为ABAB。

      > rep(c("id","use"),list(2,3))  
      [1] "id"  "id"  "use" "use" "use"  
      > rep(c("id","use"),each=2)  
      [1] "id"  "id"  "use" "use"  
      > rep(c("id","use"),2)  
      [1] "id"  "use" "id"  "use"  
      > rep(c("id","use"),unlist(2,3))  
      [1] "id"  "use" "id"  "use"  
    

    rep与list相结合

      > rep(c("id","use"),list(2,3))  
      [1] "id"  "id"  "use" "use" "use"  
    

    可以实现AABBB,与each相似。在构造一些序列时候十分好用。

  • 2、矩阵构造

    构造矩阵

      # byrow按行的顺序(横向)赋值;bycol按列(竖)赋值
      matrix(1:15,nrow=3,ncol=5,byrow=T) 
      # 只能按列(竖)赋值 
      array(1:15,dim=c(3,5)) 
    
  • 3、字符构造paste

    seq代表是ck与数值1 之间用啥记号,如:ck_1,ck*2

    collapse代表是ck1与ck2之间用啥记号如:ck1_ck2 ck1 * ck2

    字符构造paste

      paste("CK", 1:6, sep="")        
      paste("CK", 1:6, sep="*")         # 对比  
      paste("CK", 1:6,collapse = "")   
      paste("CK", 1:6,collapse = "_")   # 对比
    
  • 4、paste与list合用——批量处理

    list能够很好与paste函数应用起来

    paste与list合用

      x <- list(a="aaa", b="bbb", c="ccc")   
      y <- list(d=1, e=2)   
      z <- paste(x, y, sep="-")  
      paste("T", z, sep=":")  
    

15)数据框和列表--直接定义变量名

数据储存形式

	data.frame(wi=iris,ci=cars)   # 数据框形式,可以直接定义变量名  
	list(wi=iris,ci=cars)         # list,也可以直接定义变量名  

注意:attach()、detach()
可以将数据框中的变量释放到Rs内存中,然后就可以直接调用。

	attach(iris)  
	names(setosa)     
	detach(iris)

在data.frame中,是可以实现数据集重命名的,比如data.frame(x=iris,y=cars),也可以实现横向、纵向重命名,data.frame(x=iris,y=cars,row.names=iris)

16)names、str、unique组合使用

数据查看函数  

	names(iris)           # 查看所有变量名字  
	str(iris)             # 变量属性(int整数,num数值)  
	unique(iris$setosa)   # 查看分类变量的水平  
	table(iris$setosa)    # 分类水平,不同水平的个数(=unique+sum功能)  
	summary(iris)         # 所有变量各自的均值、分位数、众数、最大、最小值等统计量,在回归中就是系数表等  
	attributes(iris)      # 包括names(变量名)、row.names(序号的名称)、class(数据形式)

一般names、str、unique会组合使用。

17)typeof()、mode()、class()组合使用

	> gl(2,5)            # 新建一个因子  
	[1] 1 1 1 1 1 2 2 2 2 2  
	Levels: 1 2  
	> class(gl(2,5))     # 查看变量的类,显示为因子;  
	[1] "factor"  
	> mode(gl(2,5))      # 查看数据大类,显示为数值型;  
	[1] "numeric"  
	> typeof(gl(2,5))    # 查看数据细类,显示为整数型;  
	[1] "integer"  
	 
	从精细度上说,typeof>mode>class

18)逻辑运算

方法解释
!x逻辑非
x & y逻辑与
x && y逻辑与(仅匹配并返回第一个值)
x | y逻辑或
x || y逻辑或(仅返回第一个值)
x or (x,y)异或

19)数据合并-merge()函数

最常用merge()函数,但是这个函数使用时候这两种情况需要注意:

1、merge(a,b),纯粹地把两个数据集合在一起,没有沟通a、b数据集的by,这样出现的数据很多,相当于a*b条数据;

2、merge函数是匹配到a,b数据集的并,都有的才匹配出来,如果a、b数据集ID不同,要用all=T(下面有all用法的代码)。

# 横向合并

	ID<-c(1,2,3,4)  
	name<-c("Jim","Tony","Lisa","Tom")  
	score<-c(89,22,78,78)  
	student1<-data.frame(ID,name)  
	student2<-data.frame(ID,score)  
	total_student<-merge(student1,student2,by="ID")  #或者rbind()  
	total_student 

# 纵向合并

	ID<-c(1,2,3)  
	name<-c("Jame","Kevin","Sunny")  
	student1<-data.frame(ID,name)  
	ID<-c(4,5,6)  
	name<-c("Sun","Frame","Eric")  
	student2<-data.frame(ID,name)  
	total<-cbind(student1,student2)  
	total  

# merge的all用法

	> id=c("1","2","3")  
	> M=c("7","2","3")  
	> ink2=data.frame(id,M)  
	>   
	> merge(ink1,ink2,by="id",all=T)  # 所有数据列都放进来,空缺的补值为NA  
	  id    R    M  
	1  1    9    7  
	2  2    7    2  
	3  4    9 <NA>  
	4  3 <NA>    3  
	> merge(ink1,ink2,by="id",all=F)  # 默认,只取两者的共有的部分  
	  id R M  
	1  1 9 7  
	2  2 7 2  

# 其中,all=T代表全连接,all.x=T代表左联结;all.y=T代表右连接

20)cbind和rbind函数

cbind()和rbind(),cbind()按照纵向方向,或者说按列的方式将矩阵连接到一起;rbind()按照横向的方向,或者说按行的方式将矩阵连接到一起。

rbind/cbind对数据合并的要求比较严格:合并的变量名必须一致;数据等长;指标顺序必须一致。相比来说,其他一些方法要好一些,有dplyr,sqldf中的union

21)不等长合并

  • plyr包

      rbind.fill函数可以很好将数据进行合并,并且补齐没有匹配到的缺失值为NA。
    
      # 不等长合并  
      # 如何解决合并时数据不等长问题——两种方法:do.call函数以及rbind.fill函数(plyr包)  
      # rbind.fill函数只能合并数据框格式  
      # do.call函数在数据框中执行函数(函数,数据列)
    
      	library("plyr")  #加载获取rbind.fill函数  
      	# 第一种方法  
      	list1<-list()  
      	list1[[1]]<-data.frame(t(data.frame(Job_Pwordseg.ct[1])))  
      	list1[[2]]<-data.frame(t(data.frame(Job_Pwordseg.ct[2])))  
      	do.call(rbind.fill,list1)  
      	# 第二种方法
      	u<-rbind.fill(data.frame(t(data.frame(Job_Pwordseg.ct[1]))),data.frame(t(data.frame(Job_Pwordseg.ct[2]))))  
    
      核心函数是plyr包中的rbind.fill函数(合并的数据,必须是data.frame),do.call可以用来批量执行。
    
  • dplyr包

      dplyr::bind_rows() 
      
      效果是,不匹配到的放在最后,且等于NA  NA  NA  NA
    

22)语句22

23)语句23

24)语句24

25)语句25

26)语句26

27)语句27

28)语句28

29)语句29

30)语句30

posted @ 2017-05-30 22:23  银河统计  阅读(1182)  评论(0编辑  收藏  举报