sql、r

sql

mysql

** mysql正则表达式中,数字不要用\d,用[0-9]。字符句号要用两条斜线转义,如\\.
** 在mysql中查询表之前,首先要查看表的的索引字段,使用 show index from tablename来查看。
和hive不一样,mysql使用的是索引字段,尽量少用嵌套的子表,但在hive中可以先在子表中限定分区。
** mysql也可以用 EXTRACTVALUE(XML_document, XPath_string)来从xml提取数据,主要用xPath语法。
UPDATEXML(XML_document, XPath_string, new_value);

hive

在hive中可以使用正则表达式对列名进行筛选

在hive中可以使用正则表达式对列名进行筛选,但先要设置 set hive.support.quoted.identifiers=none
具体请参考:
Hive 编程专题 一 : 使用正则指定输出列

hive窗口函数、collect_set/collect_list

hive中可以使用xpath系列的函数处理xml数据

SELECT xpath_string ('b1b2', '//b') -- 结果为'b1'

参考:Hive常用函数 – 混合函数和XPath 解析 XML 函数

用R语言中的RODBC连接hive

#载入包
library(RODBC)
#新建一个连接。可能会有账户名和密码,有的不需要登陆。
ch <- odbcConnect("hiveodbc", uid = "user", pwd = "****")
#获取可以访问的表,返回data.frame
sqlTables(ch)
#提取列名
sqlColumns(ch, "tablename")
#执行sql查询语句。如果是纯数字的字符串会转化成数值型的,且数值减小8,所以用as.is=F。另外不能让字符串转化为因子。
#这两个参数设置非常重要。
sqlQuery(ch, sql, as.is=T, stringsAsFactor=F)
#将data变量表示的数据框转化成hive中表。默认rownames=T,新增一个索引列。
sqlSave(ch, data, tablename="库名.表名", rownames=F) #这个速度太慢,数据大的表不要用这种方式,可以用本地csv上传到hive中。但是在使用csv上传时,要注意建表时的语句,使用textfile格式,
如:

drop table test_20190812_yj;
– csv的
create table if not exists test_20190812_yj(
gender string,
id string,
age string
)row format serde ‘org.apache.hadoop.hive.serde2.OpenCSVSerde’ with serdeproperties
(“separatorChar” = “,”, “escapeChar” = “\”) STORED AS TEXTFILE;
;

#删除表。 指定errors = FALSE,删除不存在的表就不会报错。
sqlDrop(ch, "table name", errors = FALSE)
#关闭连接
colse(ch)

参考:R语言RODBC数据库操作

去掉字段名中的前缀表名

conn  = odbcConnect('hiveodbc')
sql = "set hive.resultset.use.unique.column.names=false"
sqlQuery(conn, sql)

hive 建立分区表

使用create table as select语句建立的表是不分区的,需要先单独建表,再插入分区的数据才能建立分区表。
1.建立分区表:
这里的table_1有两个字段,还有两个分区字段这。这里使用external tabele 建立外部表,和普通的table不一样。

create external table if not exists table_1(

        id string,

        name string)

 partitioned by (country string, city string)

 row format delimited fields terminated by ',';

2.插入数据,可以静态插入,也可以动态插入。
默认是静态插入,需要指定分区字段为一常量。如果要动态插入,需要设置一些参数,需要开启非限制的动态分区。

set hive.exec.dynamic.partition =true -- (默认false),表示开启动态分区功能;
set hive.exec.dynamic.partition.mode = nonstrict -- (默认strict),表示允许所有分区都是动态的,否则必须有静态分区字段
set  hive.exec.max.dynamic.partitions.pernode=100 -- (默认100,一般可以设置大一点,比如1000)表示每个maper或reducer可以允许创建的最大动态分区个数,默认是100,超出则会报错。
set hive.exec.max.dynamic.partitions =1000 --  (默认值) 表示一个动态分区语句可以创建的最大动态分区个数,超出报错
set hive.exec.max.created.files =10000 --  (默认) 全局可以创建的最大文件个数,超出报错。

然后,用类似下面的语句,加入数据。
注意:如果用insert into,则只会追加。而用insert overwrite,对非分区表,先清除之前数据再重写新的数据;但如果是分区表,如果在新的分区插入数据,其他分区数据则不受影响,所以如果数据量太大,无法一次性插入数据,可以建分区表,用insert overwrite分批插入,这个方法挺有用的。
注意,select后面的字段,需要和要插入的表中的字段顺序保持一致,select 结尾处的字段会自动成为动态分区字段。

INSERT OVERWRITE TABLE table_1
PARTITION (country = '中国', city) -- country是静态分区字段,为一常量;city是动态分区,由table_2中的c确定。
SELECT a, b, c  
FROM table_2 
-- table_2中的a,b 字段和tabel_1中'id'、'name'字段一致,所以table_1必须只有两个字段。table_2中的c字段会成为table_1中的分区字段"city"。如果country也是动态分区字段的,需要写成select a, b, d, c,这样table_2中的d字段会成为table_1中的分区字段country,c仍然对应city。

另外,尽量不要建立多个分区分段,而且某一个分区字段不能有很多个取值,否则会报错,因为建立了太多的分区文件。例,如果把每条记录的创建时间作为动态分区字段,因为创建时间都不一样,所以就会有几千几万个分区。需要保证作为分区的字段只取少数几个值,可以使用年,月,日等。
以上方法是有效的,我在hive上测试过了,确实可以建立分区表。
参考:
hive从查询中获取数据插入到表或动态分区
hive使用动态分区插入数据详解

hive查询结果中不显示表名:set hive.resultset.use.unique.column.names=false;

mysql中的字符串函数

  • INSTR(STR,SUBSTR)
    在一个字符串(STR)中搜索指定的字符(SUBSTR),返回发现指定的字符的位置(INDEX);
  • substring_index(“待截的字符串”,“分割符”,‘分割后的结果中取第几个’)

R笔记——基础

主要把学习工作中遇到的一些基础知识记下来,方便查看。

tryCatch()

result <- tryCatch({
	
}, warning = function(w){
	
}, error = function(e){
	paste0('错误: ', e) #这里的e就是字符串
}, finnally = {
	
}
)
  • tryCatch()本身是一个函数,是有返回值的。不报错时返回第一个表达式的结果,如果警告或者报错就返回wanining或者error的函数返回值。
  • 一定要注意,如果不需要考虑警告信息,就不要写warning = function(w)函数,如果写了这个warning函数,一定
    要在这个warining函数里写上警告信息的返回值,否则出现警告时返回为空,使代码出现意外的结果。不建议写警告处理函数。
  • 而且,在第一个参数的表达中定义的变量,在tryCatch()之外同样有效;而在tryCatch()中的function(e){}中定义的变量是局部变量,无法在tryCatcch()外面使用。
  • 无论如何,finnally中的表达式一定会执行,但不会作为tryCatch()的返回值返回。

常量

  • LETTERS: 大写字母序列;
  • letters: 小写字母序列;
  • month.abb: 月份名称缩写;
  • month.name: 月份名称;
  • pi:圆周率。

DF

  • 在第一列前插入一列
    data是一个数据框,则在第一列插入名为x的字段,值为0.
data = data.frame(x=0, data)
  • 含空字段的df
# 下面这行会报错,因为c字段没有数据。
data = data.frame(a=1, b=2, c=NULL)
# 这样就不会报错,拼出了一个含有NULL的数据框。
data = data.frame(t(as.matrix(list(a=1, b=2, c=NULL))))

日志处理(futile.logger包)

1.先编写一个日志配置文件,包括日志级别、日志文件输出格式、日志文件名和存储路径等。
2.先要source这个配置文件。
3.添加json信息。
另外,stringi包中的stri_unescape_unicode()函数可以处理日志中乱码的问题。

library(stringi)
library(rjson)
logged.info = list(info = "info_name")
logged.info$a = "a_info"
logged.info$b = "b_info"
futile.logger::flog.info(paste('info:', stri_unescape_unicode(rjson::toJSON(logged.info)),sep=' '), name = 'log.info')

内置函数

  • 分位数
#产生间隔为10%的分位点
quantile(c(1:10), seq(0, 1, 0.1))
# 也可以只取一个分位点如25%
quantile(c(1:10), c(0.25))
#去掉上面的百分号
unname(quantile(c(1:10), c(0.25)))
  • 字符串转化成命令
    eval(parse(text = ‘a = 3’))

  • rep

  • 修改数据框的列名和行名

#把数据框data的列名和行名改为"a", "b", "c"
names(data) = c("a", "b", "c")
row.names(data) = c("a", "b", "c")

分类统计

table()函数简单方便

table(c("a", "a", "b","a", "a", "b"))
  • R语言向量操作函数assign、get、mget
    (1)assign(x, value, pos = -1, envir = as.environment(pos), inherits = FALSE, immediate = TRUE)
    将value赋值给x;
    (2)get(x, pos=-1, envir=as.environment(pos), mode = “any”, inherits = TRUE)
    在指定环境中搜索名字为x的变量并返回它的值,x只能是一个字符;
    (3)mget:mget(x, envir = as.environment(-1), mode = “any”, ifnotfound, inherits = FALSE);
    与get类似,但是x可以为字符向量,返回list,每个子list对应一个字符。
  • 数据框去重。根据一个或多个字段,去掉重复行。.keep_all = TRUE表示返回所有变量。
df <- data.frame(
  x = sample(10, 100, rep = TRUE),
  y = sample(10, 100, rep = TRUE)
)
#以全部两个变量去重,返回去重后的行数
nrow(distinct(df))
nrow(distinct(df, x, y))
#以变量x去重,只返回去重后的x值
distinct(df, x)
#以变量y去重,只返回去重后的y值
distinct(df, y)
#以变量x去重,返回所有变量
distinct(df, x, .keep_all = TRUE)
#以变量y去重,返回所有变量
distinct(df, y, .keep_all = TRUE)
#对变量运算后的结果去重
distinct(df, diff = abs(x - y)
#原文链接:https://blog.csdn.net/wltom1985/article/details/54973811
  • 移动平均
    stats::filter()函数比较简单,可以求移动平均。需要加上stats包名,防止冲突。
a = c(1,2,3,4,5)
stats::filter(a/3,filter=c(1,1,1),"convolution",sides=1)
# NA NA  2  3  4
stats::filter(a/3,filter=c(1,1,1),"convolution",sides=2)
# NA  2  3  4 NA

a为一个序列,"convolution"表示求移动平均值,a/3表示三天的平均值,当sides=1时,表示过去今天,前一天和前两天的平均值;当sides=2时,表示前一天,当前和后一天的平均值。这里的filter=c(1,1,1),是每个数据前的系数,一般取1,如rep(1,3)。
请参考:
R函数详解系列——filter函数

文件系统管理

R8—批量生成文件夹,批量读取文件夹名称+R文件管理系统操作函数

R语言数据集合并、数据增减、不等长合并

如果用rbind()函数,必须要求每个数据框的列数相等,可以使用dplyr::bind_rows()方法,不要求列数相等,自动用NA填充缺失的列。
R语言数据集合并、数据增减、不等长合并

data.table

参考文章:R语言数据分析利器data.table包 —— 数据框结构处理精讲
data.table和df数据框类似,但比df效率更高,可以用它处理较大的数据文件。
常见函数有setDT(),fread(),和fwrite()

openxlsx

  • 读取数据
    直接用read.xlsx()就行
df1 <- read.xlsx(xlsxFile = xlsxFile, sheet = 1, skipEmptyRows = FALSE)
  • 写入数据
    可以新建工作簿并添加数据,也可以直接写入已有的excel。
#建立工作簿
wb <- createWorkbook()
#向工作簿中添加表
addWorksheet(wb,"sheet1")
addWorksheet(wb,"sheet2")
#将数据框添加到表格中
writeData(wb, 'sheet1', data)
writeData(wb, 'sheet2', data_2)
#保存数据框。overwrite为TRUE时,会覆盖以前的同名文件,不会报错。
saveWorkbook(wb, "path/table.xlsx", overwrite = T)

或者

write.xlsx(x, file, asTable = FALSE, ...)
  • 修饰表格
    参考:
    Rstudio中help文档,可以搜索相关函数。
    R语言openxlsx包学习
    十六进制颜色表示方法
    1.可以全局设置格式
    常用的设置包括字体、位置对齐方式:
options('openxlsx.fontName' = "Times New Roman", 'openxlsx.fontSize' = 14)
options('openxlsx.halign' = "center", 'openxlsx.valign' = "center")

其他如下:

options("openxlsx.borderColour" = "black")
options("openxlsx.borderStyle" = "thin")
options("openxlsx.dateFormat" = "mm/dd/yyyy")
options("openxlsx.datetimeFormat" = "yyyy-mm-dd hh:mm:ss")
options("openxlsx.numFmt" = NULL)
options("openxlsx.paperSize" = 9) ## A4
options("openxlsx.orientation" = "portrait") ## page orientation

2.也可以在写入时设置格式
具体如下

library(openxlsx)
library(tidyverse)
data = mtcars
data$abcbcbcbcbcbcb = mtcars$mpg
wb = createWorkbook()
addWorksheet(wb,'data')
#用系统样本
data = mtcars
# 先设置列宽,行高
setColWidths(wb, sheet = 'data', cols = 1, widths = "29")
setColWidths(wb, sheet = 'data', cols = c(2:7), widths = "15")
setRowHeights(wb, sheet = 'data', rows = 1, heights = "30")

#合并单元格
mergeCells(wb, sheet = 'data',  cols = 1:10, rows = 60) 

#首行单独设置格式
hs1 <- createStyle(fontColour = "#ffffff", #字体颜色
                   fontSize=14, 
                   fontName="Times New Roman",
                   fgFill = "#009933",#背景色
                   halign = "center", #水平
                   valign = "center", #垂直
                   textDecoration = "bold",#
                   border = "TopBottomLeftRight") #可以选上下左右边
#写入时设置格式
writeData(wb, 'data', data, 
          startCol = 1, startRow = 1, xy = NULL, #开始写入的行和列的位置
          colNames = TRUE, rowNames = F,  #列名和行名
          headerStyle = hs1,#首行的格式
          borders = "all",# 边框类型:"surrounding", "columns", "rows","all"。所有单元格用all
          borderColour = 'black',
          borderStyle = 'thin',#粗细类型,dashed,medium,thick等等
          withFilter = F, #如果为TRUE,自动打开excel中的筛选功能
          keepNA = FALSE, name = NULL, sep = ", ")


#  给数据添加渐变的颜色 type = "colourScale"
#这里的颜色是我挑选的,和excel的颜色比较接近。rule不用写,默认根据最大最小值设定颜色。
#"#009900", '#FFCC00',"#CC0000"分别是绿、黄、红
writeData(wb, 'sheet1', data)
conditionalFormatting(wb, "sheet1", cols=1:2, rows=1:50,
                      style = c("#009900", '#FFCC00',"#CC0000"),
                      #rule = c(0, 0.33, 0.67),
                      type = "colourScale")

# 给数据单元格添加条形图type = "databar" 
"#009900", '#FFCC00',"#CC0000"分别是绿、黄、红
writeData(wb, 'sheet1', data)
conditionalFormatting(wb, "sheet1", cols=1:2, rows=1:50,       type = "databar")

#设置字体等样式
#不能用options()设置,下面这个不生效:
options('openxlsx.fontName' = "Times New Roman", 'openxlsx.fontSize' = 14)
所以,需要先style = createStyle(),然后使用addStyle()添加。**一定要注意,addStyle()必须在writeData(wb, 'data', data)之后设置,在这之前设置就无效。就是所有数据处理完了再添加样式。**
示例如下:
style_1 = createStyle(fontName="Times New Roman",  # 如果要设置中文字体,中文会报错,如“宋体”应该写成'SimSun'。
                     fontSize = 15, 
                     halign = "center",
                     valign = "center")
addStyle(wb, 'sheet1', style=style_1, rows = 2:3, cols = 1:2, gridExpand = T, stack = T)
#这里的gridExpand=T, 可以作用于任意的行和列的组合。

#插入图片方法一(plot画出的图)。注意图片格式。

p1 <- qplot(mpg, data=mtcars, geom="density",
            fill=as.factor(gear), alpha=I(.5), main="Distribution of Gas Mileage")
print(p1) #需要print()出来
insertPlot(wb, 'data', xy = c("A", 35), width = 16, height = 10,  fileType = "png", units = "cm")

#插入图片方法二(本地保存的图片)

img <- system.file("yj.jpg", package = "openxlsx")
insertImage(wb, 'data',file = 'yj.png', startRow = 35, startCol = "A", width = 16, height = 10,  units = "cm")

#冻结窗口
freezePane(wb, ‘data’, firstActiveRow = 2, firstActiveCol = “B”,
firstRow = FALSE, firstCol = FALSE)

#保存工作簿
saveWorkbook(wb, ‘~/yj.xlsx’, overwrite = T)


## 交互图形。
R包:echarts4r

## 基础
### NA, NAN, NULL, Inf
NAN表示没有意义的数,是NA的子集。
具体如下:

a = c(NA, 0/0, 1/0)
a
[1] NA NaN Inf
a = c(NA, 0/0, 1/0)
a
[1] NA NaN Inf
is.na(a)
[1] TRUE TRUE FALSE
is.nan(a)
[1] FALSE TRUE FALSE

### 常用函数
* table()
查看向量或数据框的分类和相应的个数
* str()
查看对象的属性
* cut()/ levels()

a = c(4, 3, 2, 1, 2, 3, 4)
x = cut(a, breaks = c(0, 2,4, 5), labels=F, right = F, ordered_result = T)
#labels不写,默认为分组间隔,如"(0, 2]"; 可以指定 labels=F,即用整数代替分组标签; 可以指定分组名称如labels = c(“H”, “M”, “L”。
#breaks是分隔点,也可以是一个整数。
#right为T,则是右闭区间。
y = levels(x) #取分组标签

## maptools
R语言地图包,可以查看官方的pdf文档,或者参考[R语言之地图绘制](http://blog.sina.com.cn/s/blog_7147f6870102w6wq.html)

## 字符串处理函数
[参考文章](https://blog.csdn.net/duqi_yc/article/details/9817243)
### 大小写转换:toupper()和tolower()

text = “abcDEF”
toupper(text)
tolower(text)

[1] “ABCDEF”

[1] “abcdef”

### 替换:sub()、gsub()和chartr()
*功能:都是替换字符串。*
sub和gsub参数都一样,例如:(pattern = , replacement = , text),
三函数区别是:sub只替换第一个符合条件的数据,gsub替换所有符合条件的数据,这两个函数都是把字符串
作为一个整体替换;而chartr是对单个字符进行替换。

sub(“a”, “@”, ‘a1a2a3’)
#[1] “@1a2a3”
gsub(“a”, “@”, ‘a1a2a3’)
#[1] “@1@2@3”
chartr(“abc”, “123”, “a1b2c3”)#第一个参数的长度不能大于第二个参数。
#[1] “112233”

### 拼接: paste(),paste0()
格式:paste(p1, p2, sep='', collapse='')。paste0()默认sep=''

paste(c(“a”, “b”), c(“1”, “2”), sep = ‘+’)
#[1] “a+1” “b+2” 结果是含有两字符串元素的向量
paste(c(“a”, “b”), c(“1”, “2”), sep = ‘+’, collapse = ‘=’)
#[1] “a+1=b+2” 结果为一个字符串

### 拆分:strsplit()
strsplit函数使用正则表达式,使用格式为:
strsplit(x, split, fixed = FALSE, perl = FALSE, useBytes = FALSE)
- 参数x为字串向量,每个元素都将单独进行拆分。
- 参数split为拆分位置的字串向量,默认为正则表达式匹配(fixed=FALSE)。
	如果你没接触过正则表达式,设置fixed=TRUE,表示使用普通文本匹配或正则表达式的精确匹配。普通文本的运算速度快。
- perl=TRUE/FALSE的设置和perl语言版本有关,如果正则表达式很长,正确设置表达式并且使用perl=TRUE可以提高运算速度。
- 参数useBytes设置是否逐个字节进行匹配,默认为FALSE,即按字符而不是字节进行匹配。

strsplit("a,b,c, ", ‘,’)
#[[1]]
#[1] “a” “b” “c” " "


### 查询1:grep()、grepl()和match()
grep(pattern, x, ignore.case = FALSE, perl = FALSE, value = FALSE, fixed = FALSE, useBytes = FALSE, invert = FALSE)
grepl(pattern, x, ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE)
grep()返回字符串元素所在的位置,grepl()返回对应元素的逻辑结果,支持正则。
match()返回第一个匹配元素的位置,完全一样才算匹配,不支持正则。

grep(“abc " , c ( " a b c " , " d a b c e " , " a " ) ) [ 1 ] 1 g r e p l ( " a b c ", c("abc", "dabce","a")) [1] 1 grepl("abc ",c("abc","dabce","a"))[1]1grepl("abc”, c(“abc”, “dabce”,“a”))
[1] TRUE FALSE FALSE
match(“a”,c(“abc”, “a”, “bca”, ‘a’))
[1] 2


### 查询2:regexpr、gregexpr和regexec
这三个函数返回的结果包含了匹配的具体位置和字符串长度信息,可以用于字符串的提取操作。

text <- c(“Hellow, Adam!”, “Hi, Adam!”, “How are you, Adam.”)
regexpr(“Adam”, text)
#[1] 9 5 14
#attr(,“match.length”)
#[1] 4 4 4
#attr(,“useBytes”)
#[1] TRUE

gregexpr(“Adam”, text)
#[[1]]
#[1] 9
#attr(,“match.length”)
#[1] 4
#attr(,“useBytes”)
#[1] TRUE

#[[2]]
#[1] 5
#attr(,“match.length”)
#[1] 4
#attr(,“useBytes”)
#[1] TRUE

#[[3]]
#[1] 14
#attr(,“match.length”)
#[1] 4
#attr(,“useBytes”)
#[1] TRUE

regexec(“Adam”, text)
#[[1]]
#[1] 9
#attr(,“match.length”)
#[1] 4
#attr(,“useBytes”)
#[1] TRUE

#[[2]]
#[1] 5
#attr(,“match.length”)
#[1] 4
#attr(,“useBytes”)
#[1] TRUE

#[[3]]
#[1] 14
#attr(,“match.length”)
#[1] 4
#attr(,“useBytes”)
#[1] TRUE


### 提取:substr和substring
substr(x, start, stop)
substring(text, first, last = 1000000L)
它们的返回值的长度(个数)有差别:
substr返回的字串个数等于第一个参数的长度,而substring返回字串个数等于三个参数中最长向量长度,短向量循环使用。

x <- “123456789”
substr(x, c(2, 4), c(4, 5, 8))
[1] “234”
substring(x, c(2, 4), c(4, 5, 8))
[1] “234” “45” “2345678”


## stringdist()
[R语言字符串相似度 stringdist包](https://blog.csdn.net/ASSaSSINangJIE/article/details/52859157)
先安装stringdist包。stringdist用于计算对象a,b中的字符串两两之间的相似度,对于一个对象中的元素少于另一个的情况,采用循环补齐机制。stringdistmatrix的出相似度矩阵,其中采用a中的行,b中的列。

stringdist(c(“1234”, “abc”),c(“1234”, “abd”))
#[1] 0 1

比较相应位置的每个字符,返回不一样的字符数量,如果所有字符完全一样,返回0。

20180917
===============================
## switch

switch(expression, case1, case2, case3…)

以下规则适用于switch语句:
- switch()函数返回一个值,一般是匹配到的case,如果没有匹配到就返回null。
- 表达式可以是数字,也可以是字符串。如果表达式的值不是字符串,则被强制转化为整数。如果是数字,表示使用下面第几个case。
- 在switch内可有任意数量的case语句。 每个case语句后跟要比较的值和冒号。
- 如果整数的值在1和nargs() - 1(最大参数数)之间,则对条件的相应元素进行求值并返回结果。
- 如果表达式计算为字符串,则该字符串与元素的名称匹配(正好)。
- 如果有多个匹配,则返回第一个匹配元素。
- 没有默认参数可使用。
- 在不匹配的情况下,如果有一个未命名的元素,则返回其值。(如果有多个此类参数返回错误)。

x = “a”
y = 2
switch(x, a = “yang”, b = “jian”) # 与x完全匹配的那一项case。
#[1] “yang”
switch(y, a = “yang”, b = “jian”)
[1] “jian”

另外,在shiny中经常使用这种switch句式,根据不同的inputId,对某一变量赋值。怎么我在reactive用switch出问题,用if就没事?

datasetInput <- reactive({
switch(input$dataset,
rock = rock,
“pressure” = pressure,
“cars” = cars)
})


2018-09-25
==========================
p<-ggplot()...
ggplotly(p)
这样就把ggplot画的图转换成可交互的plotly图。

data = data.frame(x = c(1,2,3), y = c(2, 4, 6))
yj <-data %>% ggplot(aes(x=x, y=y)) + geom_line(color=‘red’) + geom_point(color=‘blue’)
ggplotly(yj)





2018-10-15
------------------------------------------------------------

library(RODBC)
cnx <- odbcConnect(“impalaodbc”, uid = “”, pwd = “”, DBMSencoding = “utf8”)
sql <- ‘select * from table’
#data<- sqlQuery(cnx, sql, stringsAsFactors=FALSE) #这里的语句有问题,读取的数据自己发生了变化,如字符型数字自动减8,奇怪。

data <- sqlQuery(cnx, sql, nullstring = NA_character_, na.strings = ‘NA’,stringsAsFactors=FALSE, as.is=TRUE)#这个语句读取的数据就是正确的。原因应该是as.is = TRUE这个参数
close(cnx)

shiny 教程网站
http://zevross.com/blog/2016/04/19/r-powered-web-applications-with-shiny-a-tutorial-and-cheat-sheet-with-40-example-apps/
http://yanping.me/shiny-tutorial/#deployment-web
https://blog.csdn.net/tonydandelion2014/article/details/51405021
https://blog.csdn.net/sinat_26917383/article/details/50681156

机器学习:http://www.huaxiaozhuan.com/

> data
  a b
1 1 2
2 2 3
3 3 4
将a中大于1的数赋值为0.
within(data, {a[a>1] = 0})

## Rmarkdown 2019-11-07
[参考](https://blog.csdn.net/tandelin/article/details/88572590)
[美化表格](http://haozhu233.github.io/kableExtra/awesome_table_in_html.html)

2018-10-16
==============================================
## 新环境中安装r包。
## library和require
在R中加载包是非常容易的,有两个函数可以做到:library 和 require。他们之间有一些细微的差别,但是对于在本书中的使用来说,主要的区别在于 require 会返回一个布尔值(True或False)来表示被加载的包是不是可用,而 library 函数会根据调用方式不同而有不同返回结果(这点在本书不重要)。

apply:https://blog.csdn.net/lijinxiu123/article/details/51378700

在sql中的date(),  week(), month()函数都是常用函数。如果想以周为周期来分析数据的,直接用week函数将日期转换一下。

画地图的python包:pyecharts 

2018-10-17
================================================
关于R语言中的地图包。

R语言 baidumap和REmap包使用学习(一)——baidumap包: https://blog.csdn.net/lotterychampion/article/details/51404364

Leaflet 主要是用R语言的语法封装了JS版的Leaflet,可以在R语言的plot窗口,利用html5技术显示各种地图,还可以绘制自己的要素图形。https://blog.csdn.net/allenlu2008/article/details/52816708?utm_source=blogxgwz1

这个博主关于shiny的介绍还是比较详细的
https://blog.csdn.net/u014801157/article/details/48029415?utm_source=blogxgwz0


2018-10-18
================================================
地图作图的教程:
https://blog.csdn.net/sinat_26917383/article/details/51540353
recharts: 百度ECharts 2的R语言接口:
https://madlogos.github.io/recharts/index_cn.html#-en

data = data.frame(a=c(“a”, “a”, “b”, “b”), b=c(1,1,1,3), c=c(1, 1, 2, 2), d=c(1,2,3,4))

## 排序
 在R中,和排序相关的函数主要有三个:sort(),rank(),order()、arrange()。其中R中自带排序函数有 order,sort,rank 函数,dplyr中有 arrange 函数。
  order和sort是针对向量进行操作的,arrange针对数据框。其中order返还排序后的坐标,sort返还排序后的值,arrange返还的是基于某列排序后的数据框,方便多重依据排序。

datafram数据就使用dplyr中的arrange()函数

result = arrange(data, a, desc(b))


## 分组:
### aggregate()
aggregate(data[,c('c','d')], by=list(data$a, data$b), FUN, ..., simplify = TRUE, drop = TRUE)

aggregate(data[,c(‘c’,‘d’)], by=list(mean_a = data a , m e a n b = d a t a a, mean_b = data a,meanb=datab), FUN=mean)

如上例中,使用函数是mean平均函数,没有括号。字段c和d就是要用函数计算的字段。分组字段是放在列表中的,分组组名可以重新命名。
## setdiff(), subset(), within(), nrow()

[8大Python机器学习库](https://mp.weixin.qq.com/s/2uByU8hZUPa6CdQAP-0vfw)














# tidyverse
[R&Python数据科学](https://zhuanlan.zhihu.com/zhangjingxin4)
## group_by 分组统计

summarise(count = n(), count_d = n_distinct(a[b>0]))
注意,n()计数时不能写参数,但n_distinct()可以写参数,还可以用中括号进行筛选,
而且,中括号内有多个筛选条件时,用一个“&”连接,不能用两个“&”,否则结果不对的,但不报错。
另外,这里的'count'等变量名也可以用中文表示。
## gather()和spread()
简单地说,gather()是列转行,而spread()是行转列。
请看下面的示例:

df
id class grade
1 1 a 81
2 2 b 82
3 3 a 83
4 4 b 84
5 5 a 85

6 6 b 86
7 7 a 87
8 8 b 88
9 9 a 89
10 10 b 90

* 可以使用spread()将class中的某个字段的取值拆分成多个列。

df_2 = df %>% spread(key = ‘class’, value = ‘grade’)
df_2
id a b
1 1 81 82
2 2 83 84
3 3 85 86
4 4 87 88
5 5 89 90

*也可以使用gather()将df_2中的a列和b列转换成某字段的值,就是把多列字段聚合在一起。

df_2 %>% gather(“a”, “b”, key = ‘class’, value = ‘grade’)
id class grade
1 1 a 81
2 2 a 83
3 3 a 85
4 4 a 87
5 5 a 89
6 1 b 82
7 2 b 84
8 3 b 86
9 4 b 88

10 5 b 90

## 排序

arrange(df, desc(A))

## 重命名

rename(df, A = A_1) #字段A改名为A_1

## 增加新列 

mutate(df, C = A+B)#增加C列,等于A列和B列之和

## unite()和separate()
这个一般用于字符串,也可以用于数字,就是把一列分成两列,或者把两列拼成一列。
unite()默认使用"_"来拼接,也可以用sep来指定符号。

df_3 = df_2 %>% unite(‘ab’, ‘a’, ‘b’, sep=’’)
id ab
1 1 81
82
2 2 8384
3 3 85
86
4 4 8788
5 5 89
90

separate()中一般用非数字字符的符号作为分割符,也可以用sep指定分割符,支持正则。

df_4 = df_3 %>% separate(“ab”, into=c(“a”, “b”)) #df_3得是两列及以上,如果只有一列"ab",可能报错。
id a b
1 1 81 82
2 2 83 84
3 3 85 86
4 4 87 88
5 5 89 90

注意,这里的数字都会被处理成字符串:

str(df_4)
‘data.frame’: 5 obs. of 3 variables:
$ id: num 1 2 3 4 5
$ a : chr “81” “83” “85” “87” …
$ b : chr “82” “84” “86” “88” …
str(df_2)
‘data.frame’: 5 obs. of 3 variables:
$ id: num 1 2 3 4 5
$ a : int 81 83 85 87 89
$ b : int 82 84 86 88 90

## tibble
可以使用as_tibble把dataframe转换成tibble格式,也可以直接构造一个tibble。
如果你已经熟悉了data.frame(),请注意:tibble永远不会改变输入的类型(例如,它永远不会将字符串转换为因子!)

a = tibble(a = c(“yang”, “y”), b = c(1,2))
a

A tibble: 2 x 2

a b

1 yang 1
2 y 2
#rep()中的each参数是让每个数重复多少次,times参数是整体重复多少次。

tibble(a = rep(1:3, each = 3))

A tibble: 9 x 1

  a
1 1 2 1 3 1 4 2 5 2 6 2 7 3 8 3 9 3 ``` 在引用字段时,可以使用a$a 或者 a[['a']]。 ``` > a[['a']] [1] "yang" "y" ``` 在管道符号中,要注意加个点,如'.$x' 或者'.[['a']]'。 ``` > a %>% .[['a']] [1] "yang" "y" ``` *注意,这种表示方法在管道符中比较好用,因为可以用变量名代替字段名,但还会有问题。 ``` #这里只能引用某一列,但如果在分组的summarise()中用变量名代替字段名,计算时会出问题。还是解决不了这个问题 > x = 'a' > a %>% .[[x]] #否则会把变量名直接当字段名,即认为字段为"x" [1] "yang" "y" #下面计算的是b列总和,不是分组内求和,有问题。 > x = 'b' > a %>% group_by(a) %>% summarise(count = sum(.[[x]])) # A tibble: 2 x 2 a count 1 y 3 2 yang 3 ``` ## 连接 ### 过滤连接 semi_join, anti_join 用于对数据进行筛选 ``` > m id value 1 1 2 2 2 3 3 3 4 > n id value 1 0 2 2 2 3 3 3 5 #可以在向量中指定两边连接的字段,一个等号。 #对m表进行筛选,只保留匹配到的记录。 > m %>% semi_join(n, c("id" = "id")) id value 1 2 3 2 3 4 #对m表进行筛选,只保留匹配不到的记录。 > m %>% anti_join(n, "id") id value 1 1 2 ```

常用连接

inner_join(x, y, by="key")	merge(x, y)
#如果两表中用于连接的字段名不同
left_join(x, y, by = c('left_c'='right_c'))	    merge(x, y, all.x = TRUE)
right_join(x, y)	merge(x, y, all.y = TRUE),
full_join(x, y)	    merge(x, y, all.x = TRUE, all.y = TRUE)

dplyr中的连接速度比merge()快很多。

集合操作

针对表中每行记录进行操作。
intersect(x, y):仅返回在两表中共同的行。
union(x, y):返回两表记录的并集。
setdiff(x, y):返回存在于x表中,但不在y表中的记录。(semi_join只考虑某个字段)


> union(m,n)  # 1.1的tidyverse不支持,1.2可以的。
  id value
1  1     2
2  3     5
3  3     4
4  0     2
5  2     3
> union_all(m, n)也可以,不去重
> intersect(m, n)
  id value
1  2     3
> setdiff(m,n)
  id value
1  1     2
2  3     4

字符串

library(tidyverse)
library(stringr)
R中的基础函数也可以处理字符串,但不好记忆,我每次都要上网查找,所以用stringr包,这个包要单独加载。
这个包中的函数一般以str_开头。

显示字符串原来内容,考虑转义。

> writeLines("\"")
"
> print("\"")
[1] "\""

长度

str_length(c("a", "R for data science", NA))
#> [1]  1 18 NA

拼接

可以对单个字符串拼接,也可以对含有多个字符串的向量拼接。

str_c("x", "y", sep = ", ")
#> [1] "x, y"

> name = c("yang", "jian")
> str_c(name, c("@", "$"))
[1] "yang@" "jian$"

> str_c("_", name, "_")
[1] "_yang_" "_jian_"

#str_c()是矢量化的,如果两向量的元素个数不相等,会循环执行,并抛出警告。
> str_c(name, c("@", "$", "#"))
[1] "yang@" "jian$" "yang#"
Warning message:
In stri_c(..., sep = sep, collapse = collapse, ignore_null = TRUE) :
  longer object length is not a multiple of shorter object length

# NA值处理
> str_c("a", NA)
[1] NA

> str_replace_na(NA)
[1] "NA" #字符串NA
> class(str_replace_na(NA))
[1] "character"

# 加入条件判断。空串不显示。
> a = 20
> str_c("a", "b", '', if(a>=18) "yj")
[1] "abyj"

#要将字符串向量折叠为单个字符串,请使用collapse:
str_c(c("x", "y", "z"), collapse = ", ")
#> [1] "x, y, z"

截取字符串

x <- c("Apple", "Banana", "Pear")
str_sub(x, 1, 3)
#> [1] "App" "Ban" "Pea"

# 修改和替换
str_sub(x, 1, 1) <- str_to_lower(str_sub(x, 1, 1))
x
#> [1] "apple"  "banana" "pear"

大小写及排序。(考虑语言环境)

str_to_lower()
str_to_upper()
str_to_title() #首字母大写
> str_sort(c("apple", "banana", "pear" ))
[1] "apple"  "banana" "pear"  
> str_order(c("apple", "banana", "pear" ))
[1] 1 2 3

正则表达式

str_view()和str_detect()
str_view()的返回结果不知道是啥?
str_detect()是检测与正则是否匹配,返回逻辑结果。
str_extract() 提取匹配。

> s = c("abc", "dc", "aa")
> str_detect(s, 'c$')
[1]  TRUE  TRUE FALSE
> s[str_detect(s, 'c$')]
[1] "abc" "dc"

#或者直接用下面这种方法
> str_subset(s,"c$")
[1] "abc" "dc" 

#还可以在数据框中进行筛选,直接作为管道符中的函数,类似于sum(),n()等。
#这里要注意,如果要用变量名代替某个值进行筛选,这个变量名和字段名不能重复,否则筛选无效。
> df_3
  id    ab
1  1 81*82
2  2 83*84
3  3 85*86
4  4 87*88
5  5 89*90
> df_3 %>% filter(str_detect(ab, "2$"))
  id    ab
1  1 81*82
> id = 2; df_3 %>% filter(id == id) #这里的字段名和那个变量名相同,筛选无效。

#统计匹配的数量
> x <- c("apple", "banana", "pear")
> str_count(x, "an")
[1] 0 2 0
#统计ab列中8的次数。
> df_3 %>% mutate( count = str_count(ab,"8"))
  id    ab count
1  1 81*82     2
2  2 83*84     2
3  3 85*86     2
4  4 87*88     3
5  5 89*90     1

str_extract()仅提取第一个匹配项。我们可以通过首先选择具有多于1个匹配的所有句子来最容易地看到。
str_extract_all() 以列表形式返回所有匹配到的内容。
str_extract_all(, simplify = T) 以矩阵形式返回,用空串补充。

> x
[1] "apple"  "banana" "pear"  

> str_extract(x, "[a-e]")
[1] "a" "b" "e"

> str_extract_all(x, "[a-e]")
[[1]]
[1] "a" "e"

[[2]]
[1] "b" "a" "a" "a"

[[3]]
[1] "e" "a"

> str_extract_all(x, "[a-e]", simplify = T)
     [,1] [,2] [,3] [,4]
[1,] "a"  "e"  ""   ""  
[2,] "b"  "a"  "a"  "a" 
[3,] "e"  "a"  ""   "" 

str_match()给出每个单独的组件。它返回一个矩阵,而不是字符向量,其中一列用于完整匹配,后面是每个分组的匹配,也就正则表达式中小括号中匹配的内容。
注意,有时候只是要用小括号表示重复的次数,但不想捕获括号中的内容,可以用(?:)来表示。如(?:\s){2},表示重复两次的空格,但不被分组捕获。

> sen = c("the apple", "a pen", "the banana")
> noun <- "(a|the) ([^ ]+)" #第二个括号内容表示空格以外的任何字符,重复一次或者多次。
> str_match(sen, noun)
     [,1]         [,2]  [,3]    
[1,] "the apple"  "the" "apple" 
[2,] "a pen"      "a"   "pen"   
[3,] "the banana" "the" "banana"

> noun_2 <- "(?:a|the) ([^ ]+)"
> str_match(sen, noun_2) # 只有后面一个分组了,第一个小括号中的内容没有被分组。
     [,1]         [,2]    
[1,] "the apple"  "apple" 
[2,] "a pen"      "pen"   
[3,] "the banana" "banana"

str_replace()并str_replace_all()允许您用新字符串替换匹配项。最简单的用法是用固定的字符串替换模式。

x <- c("apple", "pear", "banana")
str_replace(x, "[aeiou]", "-")
#> [1] "-pple"  "p-ar"   "b-nana"
str_replace_all(x, "[aeiou]", "-")
#> [1] "-ppl-"  "p--r"   "b-n-n-"

随着str_replace_all()您可以通过提供一个名为向量执行多个替换:

x <- c("1 house", "2 cars", "3 people")
str_replace_all(x, c("1" = "one", "2" = "two", "3" = "three"))
#> [1] "one house"    "two cars"     "three people"

可以使用反向引用来插入匹配的组件,而不是使用固定字符串替换。

> head(sentences )
[1] "The birch canoe slid on the smooth planks." 
[2] "Glue the sheet to the dark blue background."
[3] "It's easy to tell the depth of a well."     
[4] "These days a chicken leg is a rare dish."   
[5] "Rice is often served in round bowls."       
[6] "The juice of lemons makes fine punch."  
# 匹配到每句的前三个单词,用\\1方式引用和处理。    
> sentences %>% 
+     str_replace("([^ ]+) ([^ ]+) ([^ ]+)", "\\1 \\3 \\2") %>% 
+     head(5)
[1] "The canoe birch slid on the smooth planks." 
[2] "Glue sheet the to the dark blue background."
[3] "It's to easy tell the depth of a well."     
[4] "These a days chicken leg is a rare dish."   
[5] "Rice often is served in round bowls." 

> sentences %>% 
+     str_replace("([^ ]+) ([^ ]+) ([^ ]+)", "\\1_\\3_\\2") %>% 
+     head(5)
[1] "The_canoe_birch slid on the smooth planks." 
[2] "Glue_sheet_the to the dark blue background."
[3] "It's_to_easy tell the depth of a well."     
[4] "These_a_days chicken leg is a rare dish."   
[5] "Rice_often_is served in round bowls."  

str_split()最多将一个字符串分解成多个。
例如,我们可以将句子分成单词。
返回一个列表, 您可以使用simplify = TRUE返回矩阵。但要注意,特殊字符如’|'作为分割符,需要加上中括号。

> "the apple is red" %>% str_split(" ")
[[1]]
[1] "the"   "apple" "is"    "red" 

> s = 'a|b'
> str_split(s, '|')
[[1]]
[1] ""  "a" "|" "b" "" 

> str_split(s, '[|]')
[[1]]
[1] "a" "b"

str_locate()和str_locate_all()给你查找匹配项的开始和结束位置。当其他任何功能都没有完全符合您的要求时,这些功能特别有用。您可以使用它str_locate()来查找匹配的模式,str_sub()以提取和/或修改它们。

> str_locate("app_cpp", "pp")
     start end
[1,]     2   3
> str_locate_all("app_cpp", "pp")
[[1]]
     start end
[1,]     2   3
[2,]     6   7

您可以使用其他参数regex()来控制匹配的详细信息。
ignore_case = TRUE,允许字符匹配大写或小写形式。这始终使用当前区域设置。
multiline = TRUE,允许^和$匹配每一行的开头和结尾,而不是整个字符串的开头和结尾。

x <- "Line 1\nLine 2\nLine 3"
str_extract_all(x, "^Line")[[1]]
#> [1] "Line"
str_extract_all(x, regex("^Line", multiline = TRUE))[[1]]
#> [1] "Line" "Line" "Line"

comments = TRUE,允许您使用注释和空格来使复杂的正则表达式更容易理解。
dotall = TRUE,允许.匹配所有内容,包括\n。

##其他
apropos()搜索全局环境中可用的所有对象。如果您不太记得函数的名称,这将非常有用。
dir()列出目录中的所有文件。该pattern参数采用正则表达式,仅返回与模式匹配的文件名。

> dir(pattern='.*xlsx')
[1] "yj.xlsx.xlsx"

因子factors

library(tidyverse)
library(forcats)

#如果对月份排序,默认是按字母顺序排列的。如果按月份排序,应该使用因子。
x1 <- c("Dec", "Apr", "Jan", "Mar")
sort(x1)
#[1] "Apr" "Dec" "Jan" "Mar"
month_levels <- c(
  "Jan", "Feb", "Mar", "Apr", "May", "Jun", 
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
)
y1 <- factor(x1, levels = month_levels)
sort(y1)
#[1] Jan Mar Apr Dec
# Levels: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec

日期和时间

本章将重点介绍lubridate包,它使得更容易处理R. lubridate中的日期和时间不是核心整数的一部分,因为您只需要在处理日期/时间时使用它。我们还需要nycflights13来练习数据。

library(tidyverse)
library(lubridate)
library(nycflights13)

字符串转换成日期

ymd("2017-01-31")
#> [1] "2017-01-31"
mdy("January 31st, 2017")
#> [1] "2017-01-31"
dmy("31-Jan-2017")
#> [1] "2017-01-31"
ymd(20170131)
#> [1] "2017-01-31"
ymd_hms("2017-01-31 20:11:59")
#> [1] "2017-01-31 20:11:59 UTC"
mdy_hm("01/31/2017 08:01")
#> [1] "2017-01-31 08:01:00 UTC"

如果用as.Date(),

> as.Date("2018-10-30")
[1] "2018-10-30"
> as.Date("20181030")
Error in charToDate(x) : 字符串的格式不够标准明确

日期和时间转换。

as_datetime(today())
#> [1] "2018-10-25 UTC"
as_date(now())
#> [1] "2018-10-25"

读取日期和时间组件

#"2018-11-08",周四
> t = today()
[1] "2018-11-08"
> year(t)
[1] 2018
> month(t)
[1] 11
> week(t)
[1] 45
> day(t)
[1] 8
> yday(t)
[1] 312
> mday(t)
[1] 8
> wday(t)
[1] 5 
> wday(ymd('20181111'))
[1] 1
> wday(ymd('20181111'), label = T)
[1] 周日
Levels: 周日 < 周一 < 周二 < 周三 < 周四 < 周五 < 周六
> wday(ymd('20181111'), label = T, abbr = F)
[1] 星期日
Levels: 星期日 < 星期一 < 星期二 < 星期三 < 星期四 < 星期五 < 星期六
> second(now())
[1] 6.943398
> hour(now())
[1] 16
> minute(now())
[1] 27

日期计算
时间跨度(duration)
在R中,当你减去两个日期时,你得到一个difftime对象。

> h_age <- today() - ymd(19791014)
> h_age
Time difference of 14270 days
# 以秒计算时间跨度。
> as.duration(h_age)
[1] "1232928000s (~39.07 years)"
> m = ymd('20181101')
> day(m) = day(m) -5
> m
[1] "2018-10-27"
> diff = ymd('20181101') - ymd('20181031')
> diff
Time difference of 1 days

可以用函数直接构造时间跨度函数,用于计算。

dseconds(15)
#> [1] "15s"
dminutes(10)
#> [1] "600s (~10 minutes)"
dhours(c(12, 24))
#> [1] "43200s (~12 hours)" "86400s (~1 days)"
ddays(0:5)
#> [1] "0s"                "86400s (~1 days)"  "172800s (~2 days)"
#> [4] "259200s (~3 days)" "345600s (~4 days)" "432000s (~5 days)"
dweeks(3)
#> [1] "1814400s (~3 weeks)"
dyears(1)
#> [1] "31536000s (~52.14 weeks)"

如果要计算明年的今天,

> today() + dyears(1)
[1] "2019-11-08"

周期(periods)
由于上面的时间跨度是精确到秒的,在计算时过于精确,在考虑时区时会出问题。为了解决这个问题,lubridate提供了周期,以更直观的方式工作。

seconds(15)
#> [1] "15S"
minutes(10)
#> [1] "10M 0S"
hours(c(12, 24))
#> [1] "12H 0M 0S" "24H 0M 0S"
days(7)
#> [1] "7d 0H 0M 0S"
months(1:6)
#> [1] "1m 0d 0H 0M 0S" "2m 0d 0H 0M 0S" "3m 0d 0H 0M 0S" "4m 0d 0H 0M 0S"
#> [5] "5m 0d 0H 0M 0S" "6m 0d 0H 0M 0S"
weeks(3)
#> [1] "21d 0H 0M 0S"
years(1)
#> [1] "1y 0m 0d 0H 0M 0S"

间隔(interval)

> ymd("2016-01-01") %--% ymd('2017-01-01') / days(1)
[1] 366
> (ymd('2017-01-01')-ymd("2016-01-01")) / ddays(1)
[1] 366

时区
查看当前时区

> Sys.timezone()
[1] "Asia/Taipei"

修改时区,分两种情况。一是保持时间不变,转换成其他时区的时间;二是直接修改时区,会使时间改变。

t1 = now()
t2 = with_tz(now(), tzone = "Australia/Lord_Howe")
t3 = force_tz(now(), tzone = "Australia/Lord_Howe")
> t1
[1] "2018-11-08 17:53:38 CST"
> t2
[1] "2018-11-08 20:53:38 +11"
> t3
[1] "2018-11-08 17:53:38 +11"
#请忽略程序运行的时间差,即:t2 = t1
> t2-t1 
Time difference of 0.002995968 secs
> t3-t1
Time difference of -2.999998 hours

逻辑条件
在if()条件的计算结果必须要么TRUE或FALSE。如果它是一个向量,你会收到一条警告信息; 如果它是NA 或NULL,你会得到一个错误。但ifelse()与if()不一样,两者区别很大。
在if的条件中,尽量使用||和&&,这是惰性求值。或者用any()(存在一个TRUE就返回TRUE)、all()(所有为TRUE才返回TRUE)来把多个逻辑结果转换成一个逻辑结果。

> T | c(T,T,F)
[1] TRUE TRUE TRUE
> T || c(T,T,F)
[1] TRUE

向量、列表、循环
列表结构中,用一个中括号得到的还是一个列表,可以用双层中括号或者$符号获取元素。

> yj = list(a = 3, b = c(1,2))
> str(yj)
List of 2
 $ a: num 3
 $ b: num [1:2] 1 2
> str(yj[[1]])
 num 3
> str(yj$a)
 num 3
> str(yj[['a']])
 num 3

while和for循环
while更有用一些,可以控制循环的次数。

for (i in seq_along(x)) {
  # body
}

# Equivalent to
i <- 1
while (i <= length(x)) {
  # body
  i <- i + 1 
}

map函数,类似于apply函数,但比apply()函数快。

map()     返回列表。
map_lgl() 返回一个逻辑向量。
map_int() 返回一个整数向量。
map_dbl() 返回双精度向量。(
map_chr() 返回一个字符矢量。
map_df()  返回数据框。#如果调用的函数本身返回一个数据框,那么map_df()会把数据框拼在一起,类似于rbind().

#取要序列中的每个数,如果函数返回一个df,map_df()最终返回一个df
s = c(1,2,3,4,5)
f = function(x){
data.frame(a = x, grade = list(b=2x, c = 3x))
}
map_df(s, f) #要注意这里是函数名,不能写参数,不能写f(x)

比较运行速度,如果循环次数少的话,绝对时间差不大;如果循环总人数多,差距巨大。

f = function(x){x + 1}

t1 = now()
map_dbl(c(1:10000000),f)
now() -t1
#Time difference of 10.76235 secs

t1 = now()
sapply(c(1:10000000),f)
now() -t1
#Time difference of 20.59263 secs

t1 = now()
res = c()
for(x in c(1:10000000)){res = c(res, f(x))}
now() -t1
#跑了好几十分钟也跑不出来,放弃了。

map2()和pmap()
如果函数有多个参数:

f2 = function(x,y){x+y}
a = c(1,2,3)
b = c(2,3,4)
map2(a, b, f2)
[[1]]
[1] 3

[[2]]
[1] 5

[[3]]
[1] 7

pmap(list(a, b), f2) #需要放在列表中。
[[1]]
[1] 3

[[2]]
[1] 5

[[3]]
[1] 7

invoke_map()函数,调用不同的函数。

f <- c(“runif”, “rnorm”, “rpois”)
param <- list(
list(min = -1, max = 1),
list(sd = 5),
list(lambda = 10)
)
invoke_map(f, param, n = 5) %>% str()
#> List of 3
#> $ : num [1:5] 0.762 0.36 -0.714 0.531 0.254
#> $ : num [1:5] 3.07 -3.09 1.1 5.64 9.07
#> $ : int [1:5] 9 14 8 9 7


reduce()accumulate()
reduce函数采用“二进制”函数(即具有两个主输入的函数),并将其重复应用于列表,直到只剩下一个元素。
下面示例中full_join()就有两个主输入的函数。

dfs <- list(
age = tibble(name = “John”, age = 30),
sex = tibble(name = c(“John”, “Mary”), sex = c(“M”, “F”)),
trt = tibble(name = “Mary”, treatment = “A”)
)

dfs %>% reduce(full_join)
#> Joining, by = “name”
#> Joining, by = “name”
#> # A tibble: 2 x 4
#> name age sex treatment
#>
#> 1 John 30 M
#> 2 Mary NA F A

accumulate()与reduce()是类似的,但它保留了所有的中期结果。

f2
function(x,y){x+y}

a = c(1,2,3,4)
reduce(a, f2)
[1] 10
res = accumulate(a, f2)
res
[1] 1 3 6 10
str(res)
num [1:4] 1 3 6 10


谓词函数
keep()与discard(),保留或者丢弃数据;

iris %>%
keep(is.factor) %>%
str()
#> ‘data.frame’: 150 obs. of 1 variable:
#> $ Species: Factor w/ 3 levels “setosa”,“versicolor”,…: 1 1 1 1 1 1 1 1 1 1 …

some()和every(),返回T或者F,与any()、all()类似,用法不一样; 
detect()找到谓词为true的第一个元素; detect_index()返回它的位置。

keep(list(“a”, 1), is.character)
[[1]]
[1] “a”

some(c(“a”, “b”, 4), is.character)
[1] TRUE
any(is.character(c(“a”, “b”, 4)))
[1] TRUE



模型

library(tidyverse)
library(modelr)
options(na.action = na.warn)


htmlwidgets
有许多包提供htmlwidgets,包括:

dygraphs,http://rstudio.github.io/dygraphs/,用于交互式时间序列可视化。

DT,http://rstudio.github.io/DT/,用于交互式表格。

threejs,https://github.com/bwlewis/rthreejs用于交互式三维图。

DiagrammeR,http://rich-iannone.github.io/DiagrammeR/用于图表(如流程图和简单的节点链接图)。

networkD3,http://christophergandrud.github.io/networkD3/


要了解有关htmlwidgets的更多信息并查看提供它们的更完整的软件包列表,请访问http://www.htmlwidgets.org/。
leaflet: http://rstudio.github.io/leaflet/

leafletCN
https://blog.csdn.net/sinat_26917383/article/details/57083985

install.packages(“leafletCN”)
install.packages(“rgeos”)

## R地图
[R+大地图时代︱ leaflet/leafletCN 动态、交互式绘制地图(遍地代码图)](https://blog.csdn.net/sinat_26917383/article/details/57083985)



linux
# linux 定时任务
简单地说,主要分两步:
1,编辑定时任务

crontab -e


2, 一般用户执行任务

/sbin/service crond start

也可以先建立一个文件,比如a.cron,然后```crontab a.cron```

其他:

查看 
```crontab -l```
删除
```crontab -r```

每隔一分钟执行一次sh脚本,可以设置多个定时任务。

*/1 * * * * sh test.sh
00 12 * * * * sh test.sh


但是```Rscript a.R```还是不能用定时任务来启动,需要这样写

source /etc/profile
Rscript a.R

参考文章:
[linux定时任务](https://www.cnblogs.com/mingforyou/p/3930636.html)
[linux定时执行R脚本及注意事项](https://blog.csdn.net/arcers/article/details/78744219)


再学pandas
=============
一年前开始使用pandas,后来用了一段时间的r语言,现在需要重新整理一下pandas的内容。
另外,numpy可参考[NumPy中文文档](https://www.numpy.org.cn/index.html)

#引入模块
import pandas as pd
from pandas import Series, DataFrame
import numpy as np


## 创建对象

#用列表建立一个Series对象
Series([1, 2, 3, np.NaN])

0 1.0

1 2.0

2 3.0

3 NaN

dtype: float64

#用字典直接定义一个df
DataFrame({“a”:[1,2,3], “b”:[“yang”, “jian”, “shuai”]})

a b

0 1 yang

1 2 jian

2 3 shuai

利用矩阵,索引和列名建立一个df

dates = pd.date_range(‘20181114’, periods=3)
df = pd.DataFrame(np.random.randn(3,4), index=dates, columns=list(‘ABCD’))

A B C D

2018-11-14 1.263934 -1.550385 2.451117 1.319753

2018-11-15 -0.265367 -1.980790 1.241457 0.152994

2018-11-16 -1.444240 1.116383 0.873009 -2.334341


- 多重索引

#行和列都可以建立多重索引
cols = pd.MultiIndex.from_tuples([(x, y) for x in [‘A’, ‘B’, ‘C’] for y in [‘O’, ‘I’]])
inde = pd.MultiIndex.from_tuples([(x, y) for x in [‘x’, ‘y’] for y in [‘n’, ‘m’]])
df = pd.DataFrame(ndf.xs(“m”, level=1, axis=0)p.random.randn(4, 6), index=inde, columns=cols)
print(df)

可以用df.xs来选取数据,第一个参数为索引名称,axis=0表示行, level=0表示多重索引中最外层的索引

df.xs(“m”, level=1, axis=0)
df.xs(‘x’, level=0, axis=0)


## 基本功能
- 布尔值
empty,any(), all()

df

class name value m

0 True a 22.0 0

1 False a 33.0 0

2 True b 22.0 0

3 False c 10.0 0

4 True c 0.0 0

5 False c NaN 0

df.empty
#False
(df>0).any() #判断每一列是否存在大于0的元素

class True

name True

value True

m False

dtype: bool

(df>0).all() #判断每一列所有元素是否都大于0

- 复制df

df2 = df #两个变量是指同一个数据框,修改其中一个,另一个会改变。
df3 = df.copy() #建立副本,返回新的对象,修改df3,df不受影响。

- astype()强制转换
得到的dataframe中,需要保证每一列中的数据类型是一致的。可以用这种方法转换。

#将class列中所有数据转换成bool值
df[‘class’] = df[‘class’].astype(np.bool)

- reindex()
reindex()重新索引,只是调整现有索引的顺序,不能重命名,这和rename()是有区别的,
reindex()可以对横轴和纵轴的标签进行选择和排序,但不能创建新的索引名称,否则显示NaN。

df = DataFrame({“a”:[1,2,3], “b”:[“yang”, “jian”, “shuai”]})
df.reindex([2,1,0], axis = ‘index’) #也可以是axis = ‘columns’,即对列名进行重命名。为什么报错?
df.reindex(index = [2, 1, 0], columns= [“b”, “a”])

class name value m

5 False c NaN 0

5 False c NaN 0

4 True c 0.0 0

3 False c 10.0 0

2 True b 22.0 0

df.reindex(columns=[‘name’, ‘class’, ‘value’], index=[5, 5, 4, 3, 2, 9])

name class value

5 c False NaN

5 c False NaN

4 c True 0.0

3 c False 10.0

2 b True 22.0

9 NaN NaN NaN

df.reindex(df2.index) #df2可以是df的子集,实现对df的筛选。
df.reindex_like(df2)# 让df的索引和df2的索引一致。
df.rename({""})

- 迭代

for col in df:
print(col)
print(type(col))


## 查看数据
- df.head(n) #返回前n行数据
- df.tail()  #返回后n行数据
- df.columns #列信息。将列名放在列表中:list(df.columns)
- df.index   #行索引
- df.values  #返回一个表示df数据的numpy数组
- df.describe() #df的统计信息,包括各列的数量、分位点、平均值等
- df.T #转置数据,得到的也是一个DataFrame
- df.A.nlargest(n) 取A列最大的n个值 (最小:nsmallest(n))。或者df.nlargest(n, "A"),不过返回的是DataFrame。
- df.A.quantile([0.5])

查看df的列属性

df.dtypes

A float64

B float64

C float64

D float64

dtype: object

df.describe()

A B C D

count 3.000000 3.000000 3.000000 3.000000

mean -0.148558 -0.804931 1.521861 -0.287198

std 1.357861 1.677765 0.825576 1.866394

min -1.444240 -1.980790 0.873009 -2.334341

25% -0.854803 -1.765587 1.057233 -1.090674

50% -0.265367 -1.550385 1.241457 0.152994

75% 0.499284 -0.217001 1.846287 0.736374

max 1.263934 1.116383 2.451117 1.319753


## 排序
(一般情况下,axis=1是对行操作,axis=0是对列操作。)
* 按索引名称排序,axis = 1对每一行数据排序,就是依据列名称排序。axis = 0 对每一列数据排序,依据行索引大小排序。
* 按某列的值排序。默认升序。

df.sort_index(axis=1, ascending=False)

D C B A

2018-11-14 1.319753 2.451117 -1.550385 1.263934

2018-11-15 0.152994 1.241457 -1.980790 -0.265367

2018-11-16 -2.334341 0.873009 1.116383 -1.444240

df.sort_index(axis=0, ascending=False)

A B C D

2018-11-16 -1.444240 1.116383 0.873009 -2.334341

2018-11-15 -0.265367 -1.980790 1.241457 0.152994

2018-11-14 1.263934 -1.550385 2.451117 1.319753

df.sort_values(by=‘B’)

A B C D

2018-11-15 -0.265367 -1.980790 1.241457 0.152994

2018-11-14 1.263934 -1.550385 2.451117 1.319753

2018-11-16 -1.444240 1.116383 0.873009 -2.334341


## 选择数据
* 选择行,返回第m到n-1行数据,dataframe。

#这里必须是切片操作,如果写成df[0], 会报错。
df[m:n]

* 选择列,返回Series

df[“A”]
df.A

*  df.loc[,]
第一个参数表示行索引名称,第二个参数表示列索引名称,两个参数都可以加中括号,返回的结果的维度不一样。

#两参数都有中括号,返回二维的数据框
type(df.loc[[dates[0]], [“A”]])
#pandas.core.frame.DataFrame
#返回Series
type(df.loc[dates[0], [“A”]])

pandas.core.series.Series

#返回标量
type(df.loc[dates[0], “A”])

numpy.float64

df.loc[‘2018-11-14’:‘2018-11-15’,[‘A’,‘B’]]

A B

2018-11-14 1.263934 -1.550385

2018-11-15 -0.265367 -1.980790

* df.iloc[,]
按索引位置的序号来选择数据。

df.iloc[0] #选择第0行数据,Series
df.iloc[0:1, 0:2] #选择第0行,第0,1列数据。切片选择范围时不包括最后一个数字。
df.iloc[0, 0] #获取第0行、第0列的标量数据。
df.iloc[[0], [0]] #获取第0行、第0列的DataFrame数据框。
df.iloc[:, 0:2] #获取所有行、第0、1列

* 布尔索引
常用布尔结果对数据进行筛选。这里貌似只能筛选行。

df[‘A’]>0

2018-11-14 True

2018-11-15 False

2018-11-16 False

Freq: D, Name: A, dtype: bool

df[[True, False, False]] #只显示为True的行。
df[df[‘A’]>0] #筛选A列大于0的行
df[(df[‘A’]<0) & (df[‘B’]>0)] #筛选A列小于0且B列大于0的行,需要括号包裹两个条件。
df[(df[‘A’]<0) | (df[‘B’]>0)] #筛选A列小于0或B列大于0的行,需要括号包裹两个条件。
df[(df[‘A’]<0) ^ (df[‘B’]>0)] #对称差集,在两集合中的并集中剔除交集的部分。
df[~(df[‘A’]<0)] #补集
df2

A B C D E

2018-11-14 1.263934 -1.550385 2.451117 1.319753 m

2018-11-15 -0.265367 -1.980790 1.241457 0.152994 n

2018-11-16 -1.444240 1.116383 0.873009 -2.334341 t

df2[df2[‘E’].isin([‘m’, ‘n’])] #筛选E列中值在[‘m’, ‘n’] 范围内的数据。这里的isin()相当于R语言中的%in%.

A B C D E

2018-11-14 1.263934 -1.550385 2.451117 1.319753 m

2018-11-15 -0.265367 -1.980790 1.241457 0.152994 n


- 新增及修改字段 assign(),类似R语言tideyverse包中的mutate()函数

修改df中的Value字段,并增加新列Value_2,返回新的数据框。这里的x是调用该方法的对象。

df = pd.DataFrame({‘Color’: ‘Red Red Red Blue’.split(),‘Value’: [100, 150, 50, 50]})
df.assign(Value = lambda x:x.Value+1,
Value_2 = lambda x:x.Value+2)

## 数据计算
包括统计学函数、窗口函数等。参考[pandas官方文档](http://pandas.pydata.org/pandas-docs/stable/user_guide/computation.html)
- 移动窗口操作 rolling()

df = pd.DataFrame({“a”:range(9)})
df.a.rolling(3, center=False).sum() #这里以三条记录为一组,即某一行及前两行的记录;如果center=True,则取某行及前一行和后一行的记录。
df.a.rolling(2).mean()#移动平均

或者直接用df来调用

dates = pd.date_range(‘20181114’, periods=6)
df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list(‘ABCD’))
df.rolling(2, center=True,on=“A”).sum()#默认是以index为观察目标的,如果用on=“A”,则指定观察目标为"A"列,即对移动A列。

- resample()
对于时间和日期索引的dataframe数据,用resample()函数可以选择不同时间间隔作为分组。

idx = pd.date_range(‘1/1/2019’, periods=80, freq=‘d’)
df3 = pd.DataFrame({“no”:range(80), “b”:range(1, 81,1)}, index=idx)
df4 = df3.drop(df3.index[[2,3]], axis = 0) #故意删掉两个日期索引2019-01-03, 2019-01-04,
df4
df4.resample(‘5d’).sum()#统计每五天的数据之和,这里仍然是以1号到5号为一组进行求和,是以固定日期来分组,而不是日期索引的数量来分组。
df4.resample(‘5d’).ohlc()#开始、结束、最高、最低

## 条件赋值
对符合某些条件的字段赋新值

#直接修改原df,注意等号左右两边的对象不一定一致,左边可以是dataframe,右边可以是常量。
df.loc[‘2018-11-14’, “A”] = 0
#将df中大于0的数据变成负的。df[df>0]的返回结果中不符合条件的数据用NaN表示。
df[df>0] = -df
#先根据布尔条件筛选数据,然后再设置值
df.loc[df[df[‘A’]<0].index, “A”] = 0
df.loc[df.A<0, [“A”]] = 0
#多个条件,这里用np.where()
df[‘A’] = np.where(df[‘A’] > 5, ‘high’, ‘low’)


## 缺失值处理

## 统计操作。
* 可以使用常见的统计函数。
df.count()
df.mean()等
* 也可以使用自定义函数。
apply()用于DataFrame中的列或行。
applymap()用于DataFrame中的每一个元素。
map()函数作用于一个Series的每一个元素,注意,mpa(f)中的参数f不但可以是函数,也可以Series的映射。

#将自定义函数应用于每一列,这里的x就是默认为列,也可以指定第二个参数为0。
df = pd.DataFrame({“A”:[1,2,3,4], “B”:[3,4,5,6]})
df.apply(lambda x: x.max() - x.min(), 0)
#第二个参数为1,将自定义函数应用于每一行。
df.apply(lambda x: x.max() - x.min(), 1)
df.applymap(lambda x:0)
df[“A”].map(lambda x : 1)

这里的s是Series格式,可以作为一种函数映射关系

s = pd.Series({1:“a”, 2:“b”, 3:“c”})
df[“A”].map(s)


## 合并与连接
* concat()
pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,
          keys=None, levels=None, names=None, verify_integrity=False,
          copy=True)

df1 = pd.DataFrame({‘A’: [‘A0’, ‘A1’, ‘A2’, ‘A3’],
‘B’: [‘B0’, ‘B1’, ‘B2’, ‘B3’],
‘C’: [‘C0’, ‘C1’, ‘C2’, ‘C3’],
‘D’: [‘D0’, ‘D1’, ‘D2’, ‘D3’]},
index=[0, 1, 2, 3])

df2 = pd.DataFrame({‘A’: [‘A4’, ‘A5’, ‘A6’, ‘A7’],
‘B’: [‘B4’, ‘B5’, ‘B6’, ‘B7’],
‘C’: [‘C4’, ‘C5’, ‘C6’, ‘C7’],
‘E’: [‘E4’, ‘E5’, ‘E6’, ‘E7’]},
index=[3, 5, 6, 7])
#将多个数据框放在一个列表中,默认按列操作,就是把数据框上下拼接在一起,可以存在相同的行索引。
pd.concat([df1, df2],keys=[‘x’, ‘y’]) #选择所有的列,并添加外层索引[‘x’,‘y’]

pd.concat([df1, df2], join=‘inner’) #选择共同的列

A B C

0 A0 B0 C0

1 A1 B1 C1

2 A2 B2 C2

3 A3 B3 C3

3 A4 B4 C4

5 A5 B5 C5

6 A6 B6 C6

7 A7 B7 C7

pd.concat([df1, df2], axis=1) #选择所有的行

A B C D A B C E

0 A0 B0 C0 D0 NaN NaN NaN NaN

1 A1 B1 C1 D1 NaN NaN NaN NaN

2 A2 B2 C2 D2 NaN NaN NaN NaN

3 A3 B3 C3 D3 A4 B4 C4 E4

5 NaN NaN NaN NaN A5 B5 C5 E5

6 NaN NaN NaN NaN A6 B6 C6 E6

7 NaN NaN NaN NaN A7 B7 C7 E7

pd.concat([df1, df2], axis=1, join=‘inner’) #选择共同的行

A B C D A B C E

3 A3 B3 C3 D3 A4 B4 C4 E4

*  merge()
pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
         left_index=False, right_index=False, sort=True,
         suffixes=('_x', '_y'), copy=True, indicator=False,
         validate=None)
类似于sql中连接操作。how参数指定连接方式, on、lef_on、right_on可以指定连接的索引名称。
*  append()
你可以DataFrame通过传递一个Series或一个dict来 向a追加一行append,这将返回一个新的DataFrame。

s2 = pd.Series([‘X0’, ‘X1’, ‘X2’, ‘X3’], index=[‘A’, ‘B’, ‘C’, ‘D’])
df1.append(s2, ignore_index=True)

A B C D

0 A0 B0 C0 D0

1 A1 B1 C1 D1

2 A2 B2 C2 D2

3 A3 B3 C3 D3

4 X0 X1 X2 X3

* align()

df.align(df2, join=‘inner’)



## 重塑和数据透视表
pivot() 类似于R语言tidyverse包中的spread(),就是把行转列。但是列转行用melt()
melt()
df.pivot(index='date', columns='variable', values='value')

df

name subject score

0 A Math 84

1 A English 89

2 A History 70

3 B Math 90

4 B English 84

5 B History 59

6 C Math 72

7 C English 62

8 C History 54

df2 = df.pivot(index=“name”, columns=‘subject’, values=‘score’)

subject English History Math

name

A 89 70 84

B 84 59 90

C 62 54 72

stack():针对多重索引


pivot_table() 类似于excel中的数据透视表,主要参数包括行,列,值,聚合函数。
pd.pivot_table(df, values='D', index=['A', 'B'], columns=['C'], aggfunc=np.sum)
crosstab()交叉表,计算频数,对不同字段的取值进行分类统计。

df1

A B C D

0 A0 B0 C0 D0

1 A1 B1 C1 D1

2 A2 B2 C2 D2

3 A3 B3 C3 D3

pd.crosstab(df1.A, df1.B) # 如果添加参数normalize=True,得到的是比例。

B B0 B1 B2 B3

A

A0 1 0 0 0

A1 0 1 0 0

A2 0 0 1 0

A3 0 0 0 1


pd.cut()将连续变量转换成离散变量。


## groupby

可以根据列名分组,也可以根据不同级别索引来分组。
分组统计,直接调用聚合函数

df = DataFrame({“name”:[“a”,“a”, “b”, “c”, “c”, “c”], “class”:[1, 0, 1, 0, 1, 0], “value”:[22, 33, 22, 10, 0,np.NaN]})

class name value

0 1 a 22.0

1 0 a 33.0

2 1 b 22.0

3 0 c 10.0

4 1 c 0.0

5 0 c NaN

只返回某个分组下的结果

a = df.groupby([“name”])
a.get_group(“a”)

#对name分组并统计每一列的数量,不包括np.NaN
df.groupby([“name”]).count()

class value

name

a 2 2

b 1 1

c 3 2

#k只统计某一列,返回的是Series
df.groupby([“name”])[‘value’].count()

name

a 2

b 1

c 2

Name: value, dtype: int64

#value_counts()也可以统计不同取值的数量。
df.name.value_counts()

#取每个分组第0行。first(),last()等
df.groupby([“name”]).nth(0)

class value

name

a 1 22.0

b 1 22.0

c 0 10.0

#分组并筛选
df.groupby([“name”])[‘value’].filter(lambda x:x.sum()>20)
#也可以取最大值df.groupby([“name”])[‘value’].max()

0 22.0

1 33.0

2 22.0

Name: value, dtype: float64

对value字段进行多方面统计,注意聚合函数放在列表中。

df.groupby([“name”])[‘value’].agg([np.mean, np.sum, np.min, np.size])

mean sum amin size

name

a 27.5 55.0 22.0 2.0

b 22.0 22.0 22.0 1.0

c 5.0 10.0 0.0 3.0

#也可以对结果中列名重新定义。重命名,也可以对行索引进行重命名。
df.groupby([“name”])[‘value’].agg([np.mean, np.sum, np.min, np.size]).rename(columns={“mean”:“me”, “sum”:“su”, “amin”:“am”, “size”:“si”})

#分组后,对不同字段使用不同的函数
df.groupby([“name”]).agg({“class”: lambda x: max(x) - min(x), “value”: np.sum})

class value

name

a 1 55.0

b 0 22.0

c 1 10.0

#使用get_group()获取某分组条件下的group,注意入参为元组。这里获取的是name为c,class为0的组。
df.groupby([“name”, “class”]).get_group((‘c’, 0))

class name value

3 0 c 10.0

5 0 c NaN

#对分组进行迭代。
for name, group in df.groupby([“name”]):
print(name)
print(type(group))

a

b

c

#对每个分组内的记录进行单独标注行数
df.groupby([“name”]).cumcount()

0 0

1 1

2 0

3 0

4 1

5 2

dtype: int64

## 时间序列
- 索引为日期格式
Timestamp:  表示单个时间戳 to_datetime, Timestamp
DatetimeIndex:   Timestamp  to_datetime,date_range,bdate_range,DatetimeIndex
Period: 表示单个时间跨度  Period
PeriodIndex: Period period_range, PeriodIndex

pd.date_range(‘2018-11-15’, periods=10, freq=‘D’)

DatetimeIndex([‘2018-11-15’, ‘2018-11-16’, ‘2018-11-17’, ‘2018-11-18’,

‘2018-11-19’, ‘2018-11-20’, ‘2018-11-21’, ‘2018-11-22’,

‘2018-11-23’, ‘2018-11-24’],

dtype=‘datetime64[ns]’, freq=‘D’)

- dt
如果某一列是日期格式,则Series可以用dt分析。

import datetime
import pandas as pd
s = pd.Series(pd.date_range(‘2012-1-1’, periods=5, freq=‘D’))
print(s)
print(s.max()-s)
s2 = s + datetime.timedelta( days = 1, hours = 1, minutes = 5, seconds = 59)
print(s2)
print(s2.dt.year)

详细点:

df = DataFrame(pd.date_range(‘2018-11-15’, periods=6, freq=‘D’), columns = [“date”])

date

0 2018-11-15

1 2018-11-16

2 2018-11-17

3 2018-11-18

4 2018-11-19

5 2018-11-20

df[‘date’].dt.year

0 2018

1 2018

2 2018

3 2018

4 2018

5 2018

Name: date, dtype: int64

df[‘date’][df[‘date’].dt.day > 18]

4 2018-11-19

5 2018-11-20

Name: date, dtype: datetime64[ns]



## 字符串
Series和Index配备了一组字符串处理方法,可以轻松地对阵列的每个元素进行操作。也许最重要的是,这些方法会自动排除缺失/ NA值。这些是通过str属性访问的。
str属性是Series和Index具有的,不能用DataFrame直接调用,可以使用apply()

s = Series(["Alice B ", " d ef ", ‘hello world’, ‘yang.j’, ‘jian.yang’])

0 Alice B

1 d ef

2 hello world

3 yang.j

4 jian.yang

dtype: object

s.str.upper() #大写
s.str.lower() #小写
s.str.capitalize() #首字母大写
s.str.len() #长度
s.str.strip() #去掉首尾空格
s.str.lstrip()#去掉首部空格
s.str.rstrip()#去掉尾部空格
s.str.replace(" ", “.”, regex=False) #把字符串中的空格替换成.符号,不使用正则。也可以支持正则及re.compile()对象。
s.str.split(’ ') #根据空格分割

0 [Alice, B, ]

1 [, , d, ef, , ]

2 [hello, world]

3 [yang.j]

4 [jian.yang]

dtype: object

s.str.get(0) #获取第0个字符
s.str.split(’ ‘,expand=True, n=2) #这里的n是指只使用前n个分割符。
s.str.rsplit(’_’, expand=True, n=1) #反向分割
s.str[0]#获取第0个字符,和上面一样

0 A

1

2 h

3 y

4 j

dtype: object

s.str.cat(sep=’_’)#用符号把所有字符串连接成一个字符串。

‘Alice B _ d ef _hello world_yang.j_jian.yang’

s.str.cat(list(‘01234’), sep=’_’) #也可以和同样大小的列表拼接。这里也可以把df的两列拼在一起。

0 Alice B _0

1 d ef _1

2 hello world_2

3 yang.j_3

4 jian.yang_4

dtype: object

#该extract方法接受具有至少一个捕获组的正则表达式。
#但要注意,所有的正则表达式必须有一个或多个分组,也就是正则的引号内要有一组或多组括号。
s.str.extract(r’a’) #这样写会报错。
s.str.extract(r’(a)’) #这样写是正确的。
#正则中有两个分组,并用P来命名,对应结果中两列的列名。由于直接生成多列,有时比split()好用。
s.str.extract(r’(?P\w?)(?P\w+)’,expand=True) #在未来的版本,expand=True返回DataFrame.

col_1 col_2

0 A lice

1 d

2 h ello

3 y ang

4 j ian

s.str.extractall()#提取所有匹配内容。

#匹配,返回True或False.
pattern = r’a’
s.str.contains(pattern) #支持正则,可以理解成包含,类似于re.search()。

0 False

1 False

2 False

3 True

4 True

dtype: bool

s.str.match(pattern)#支持正则,类似于re.match(),从首字符开始匹配。

0 False

1 False

2 False

3 False

4 False

dtype: bool

## tidy数据
与R语言中的管道符号相似,pandas也有类似的使用方式。
比如以下示例中,每一步操作都用“点”符号连接,且是在上一步的返回结果上进行的。整个代码需要放在一个括号中,否则会报错。

df = pd.DataFrame({‘Color’: ‘Red Red Red Blue’.split(),‘Value’: [100, 150, 50, 50]})
res = (
df .rename(columns={“Color”:“color”}) #修改字段名,返回新的数据框,这一步的返回结果已经不是df了。
.assign(x = lambda x:x.color, #注意:这里的x是调用该方法的新数据框,不是df,所以用小写的color
y = df.Color) #这里用的是原数据框df,所以字段名是大写的Color
.sort_index()
.groupby([“color”])
.agg(“count”)
.loc[:,[“x”, “y”]]#最后只选择新增的两个字段x,y
)
print(res)

## 效率和内存
- 可以使用cython、numba等方法,提升程序运行速度。

import numba
import numpy as np
import pandas as pd
@numba.jit
def abc(x):
for i in range(10000):
for j in range(100):
for k in range(100):
x = 0
%timeit abc(10) #jupyter中可以使用这个命令来计算运行时间。

- 节约存储空间:
如果某一字段是存量大量重复值的字符串,如性别、省份、学历等,可以把这一列转换成category类型时,pandas会用一种最省空间的int子类型去表示这一列中所有的唯一值,以节省存储空间。

data[‘a’] = data[‘a’] .astype(‘category’)

另外,由于数值型数据有多种存储格式,如int8、int32等,函数pd.to_numeric()可以对数值型数据进行向下类型转换,以节省存储空间


## 因子
指分类数据 dtype="category",类似于R语言中的factor。
df["B"] = df["A"].astype('category')。可以降低字符串数据占用的内存。

## 文件读写
- 生成和读取excel

#生成
DataFrame.to_excel(excel_writer, sheet_name=‘Sheet1’, na_rep=’’, float_format=None, columns=None, header=True, index=True, index_label=None, startrow=0, startcol=0, engine=None, merge_cells=True, encoding=None, inf_rep=‘inf’, verbose=True, freeze_panes=None)
‘’’
该函数主要参数为:excel_writer。
excel_writer:写入的目标excel文件,可以是文件路径、ExcelWriter对象;
sheet_name:被写入的sheet名称,string类型,默认为’sheet1’;
engine:也很重要,可以与openpyxl库对接。
na_rep:缺失值表示,string类型;
header:是否写表头信息,布尔或list of string类型,默认为True;
index:是否写行号,布尔类型,默认为True;
encoding:指定写入编码,string类型。
‘’’
import pandas as pd
writer = pd.ExcelWriter(path) #path为工作簿的路径和名称
data.to_excel(writer, ‘sheet1’) #sheet1为工作表的名称, data为DataFrame数据
writer.save()#保存数据的步骤不能少

#读取
pd.read_excel(io, sheetname=0, header=0, skiprows=None, skip_footer=0, index_col=None, names=None, parse_cols=None, parse_dates=False, date_parser=None, na_values=None, thousands=None, convert_float=True, has_index_names=None, converters=None, dtype=None, true_values=None, false_values=None, engine=None, squeeze=False, **kwds)
‘’’
该函数主要的参数为io、sheetname、header、names、encoding。
io:excel文件,可以是文件路径、文件网址、file-like对象、xlrd workbook;
sheetname:返回指定的sheet,参数可以是字符串(sheet名)、整型(sheet索引)、list(元素为字符串和整型,返回字典{‘key’:‘sheet’})、none(返回字典,全部sheet);
header:指定数据表的表头,参数可以是int、list of ints,即为索引行数为表头;
names:返回指定name的列,参数为array-like对象。
encoding:关键字参数,指定以何种编码读取。
该函数返回pandas中的DataFrame或dict of DataFrame对象,利用DataFrame的相关操作即可读取相应的数据。
‘’’
data = pd.read_excel(‘excel文件的路径和名称’)
print(data)



## 其他
找出出现次数最多的元素。

s = pd.Series([1, 1, 3, 3, 5, 5, 7, 7, 7])
s.mode()

pd.mode()
[参考文档](http://pandas.pydata.org/pandas-docs/stable/io.html#reading-excel-files)

你可能感兴趣的:(R,sql)