把学习过程记载下来,加深印象,到时要是忘了也容易查,有需要的同学也可以参考:
1、包的安装:两种方法:一种通过R的菜单,先设定cran镜像,然后安装程序包,会出来一个列表,选择相应程序包安装,安装完毕再点击加载程序包,找到要加载的程序包即可;另一种通过命令行代码:先install.packages("包名")安装,然后library("包名")加载;
2、要善于使用帮助文档,help(“对象名称”)就可以得到相应的帮助文档了,help.search(“对象名称”,rebuild=TRUE),这个rebuild是针对一些新安装的包,需要刷新帮助文档数据库。
2、通过RODBC操作数据库:先建立好odbc数据源,然后就可以在R中通过RODBC的方法操作数据库
odbcDataSources():列出当前可用的odbc数据源
conn=odbcConnect("PostgreSQL30",uid='postgres',pwd='postgres'):建立一个连接
result=sqlQuery(conn,'select * from rtest'):执行一个查询,并把返回来的sql查询结果赋值给result,注意这里要写上通道名conn,即是前面建立的连接
sqlQuery(conn,"insert into rtest(id,cust_name) values('3','stephen')"):插入、更新、查询都是用sqlQuery方法。注意这里有个技巧,由于R语言单引号和双引号都可以起到相同的文本引号作用,并且单引号在双引号内或者双引号在单引号内均不需要转义符,所以可以外层用双引号,sql语句用单引号。
sqlSave(conn,result,tablename='rsave'):把数据result保存到表rsave,如果rsave表不存在则自动创建,这个函数有很多参数,建议先help("sqlSave")再用
补:在64位系统用32位driver链接32位数据库,有时sqlSave在某些书库会出错(比如同样操作,td出错,pg正常),原因大概是RODBC默认情况下对一些数据库的字段类型判断错误,可以通过参数varTypes指定字段的类型来解决问题,比如
sqlresult=sqlQuery(conn,"select id,bd,name from test2")
sqlSave(conn,sqlresult,tablename="test",varTypes=c(id="varchar(2)",bd="date"))
我主要是在td出错,其他数据库未验证。
##----------
odbcClose(conn):关闭连接
odbcCloseAll():关闭所有连接;
终于找到一个dm工具可以直接读库、写库了!oh,yeah!
3、java调用r:需要通过RServe包,像其他包一样安装加载,然后通过Rserve()启动服务(每次运行java调用代码都需要确保服务已启动),就可以开始写java代码了。
需要引入两个jar包:Rengine.JAR和RserveEngine.JAR,调用的代码如下,注意需要抛出异常:
import org.rosuda.REngine.REXP;
import org.rosuda.REngine.REXPMismatchException;
import org.rosuda.REngine.Rserve.RConnection;
import org.rosuda.REngine.Rserve.RserveException;
RConnection c =new RConnection();
System.out.println("connected");
REXP x=c.eval("R.version.string");
System.out.println(x.asString();
4、备忘一些 好用函数:
class(x) #获取x的对象类别
apply(x,c(1,2),mean)#按行1或者列2对x求平均值;
tapply(x,y,mean)#按照y分类,分别求x的平均值;
library(RODBC)
#conn=odbcConnect('mydb')
data=sqlQuery(conn,"select cid,r_score_fx,f_score_fx,m_score_fx,rfm_score_fx from t1")
#定义8类,迭代次数50;分别选择10次随机中心点,默认值是1,多选择几次有利于改善聚类结果
ks=kmeans(cbind(data$R_SCORE_FX,data$F_SCORE_FX,data$M_SCORE_FX),8,iter.max=50,nstart=10)
20131223补充:实际应用中,同一批样本数据、同样的代码,前后两次聚类结果出现不同,原因是kmeans聚类开始时会随机选择初始点,初始点不一样,会导致
聚类结果有所不一样,但理论上每次结果大部分的记录分类情况应该是一样的(还没验证)。
现在的问题是,是否我指定初始点就可以重现结果?如何选取初始点,语法上如何指定?
#构造数据框,用于下面的方差分析,注意这里要对cluster转换成factor
r_score_fx=data.frame(x=data$R_SCORE_FX,a=factor(ks$cluster))
f_score_fx=data.frame(x=data$F_SCORE_FX,a=factor(ks$cluster))
m_score_fx=data.frame(x=data$M_SCORE_FX,a=factor(ks$cluster))
#方差分析,注意表达式的意义:x是响应变量,a是因子,p值小于0.05说明存在显著差异,表示聚类结果有效
r_score_fx.aov=aov(r_score_fx$x~r_score_fx$a,data=r_score_fx)
f_score_fx.aov=aov(f_score_fx$x~f_score_fx$a,data=f_score_fx)
m_score_fx.aov=aov(m_score_fx$x~m_score_fx$a,data=m_score_fx)
summary(r_score_fx.aov)
summary(f_score_fx.aov)
summary(m_score_fx.aov)
#多重T检验,p值小于0.05说明存在显著差异,表示聚类结果有效
r_score_fx.test=pairwise.t.test(r_score_fx$x,r_score_fx$a,p.adjust.method='BY')
f_score_fx.test=pairwise.t.test(f_score_fx$x,f_score_fx$a,p.adjust.method='BY')
m_score_fx.test=pairwise.t.test(m_score_fx$x,m_score_fx$a,p.adjust.method='BY')
r_score_fx.test
f_score_fx.test
m_score_fx.test
result=cbind(data,ks$cluster)
date()
tapply(result$M_SCORE_FX,ks$cluster,mean) #按聚类类别对r求平均值
#这个效率不行啊,写到pg还可以接受10几万条记录用了2分钟,写到td就悲剧了,用40+分钟,亟需优化,不然玩不下去,
#teradataR找不到写库的函数
sqlSave(conn,result,tablename='t2',rownames=FALSE)
20131223补充:teradataR可以写库!具体见后面第九点。
(2013-09-10)
6、factor分类与显示(转):分类的目标字段必须为factor类型
我们对数据进行分类统计时便要用到 factor 数据。一般 factor 类型的数据在数据库中都会以整数存储以节省数据库空间,这样就需要解决 factor 的分类和显示问题。假设有一个公司部门的数据 x,1代表行政部,2代表财务部,3代表销售部,我们如果只要对1和2做分类统计的话,可以使用以下方法。
new_x <- factor(x, levels=c(1, 2))
对于这样的操作,所有原来是3的数据都会被处理为 NA。假设我们还想把1和2显示成字符串。
new_x <- factor(x, levels=c(1, 2), labels=c("行政部", "财务部"))
labels 这个参数根据 levels 中的排序,依次将整数替换成字符串,方便显示。
7、
数字vector分区间统计:对数值型字段快速分段
除了按照字符型类别去统计数据时,我们往往还需要按照数字区间进行分类统计。假设我们要按照一家公司员工的入职天数进行分类,统计不同区间的人数时,就要用到分区间的技巧。分区间一般使用 cut 函数。
f <- cut(days, breaks=c(0, 100, 200))
以上函数将入职天数 days 按照 breaks 参数设定的数字值,将 days 分为两大类,(0, 100] 和 (100, 200]。注意,默认区间最左侧值不包含,右侧值包含。如果想要包含最小值 0 ,采用如下写法。
f <- cut(days, breaks=c(0, 100, 200), include.lowest=T)
cut 函数将返回一个 factor 类型数据,即可以对这类数据进行分类统计。如
tapply(!is.na(days), f, sum)
将分别计算入职天数在 [0, 100]和(100, 200]的人数。
8、决策树
library(RWeka) #加载这个包,可以调用Weka的所有算法(Weka是java实现的,本质上是调用一个java类,所以需要依赖rJava,R安装和加载一个包时会自动安装加载依赖包
library(party) #需要使用party包中的plot()来拟合二叉树,问题是这个二叉树太简单了,能不能拟合出类似modeler那种n叉树呢?
data(iris)
m1=J48(iris$Species~.,data=iris) #注意分类目标变量必须是factor类型的
summary(m1)
table(iris$Species,predict(m1))
if(require('party',quietly=TRUE))plot(m1) #require功能上类似于library,但require会返回逻辑值。
9、使用teradataR
已聚类为例,演示teradataR的使用
library(teradataR)
tdConnect('mytd') ##生成一个tdConnection的连接通道,也可以tdConnection=odbcConnect(‘mytd’)实现
tdf=td.data.frame('tableName','databasename')
tdf22=subset(subset(tdf,lc==22),if_trade=='1') ##子集
tkm22=td.kmeans(tdf22[27:48],centers=3) ##产生一个聚类模型
nt22=predict(tkm22,tdf22,'newtable','databasename') ##应用聚类模型对每条记录聚类,会创建newtable表,写回仓库
有时生成新字段并且需要写回数据库:
tdf22['newCol']=tdf22['lc']/2
tdf22.writetest=as.td.data.frame(tdf22,tableName='newTable',database='databaseName') ##创建新表newTable
td.merge(tdf1,tdf2,‘newtable’)这个函数不靠谱,如果tdf1,tdf2带有条件,合并时条件失效,相当于将tdf1、2指向的两个表直接合并,没有判断条件