文档章节

R语言学习笔记之六

o
 osc_1ee7cxmx
发布于 2018/08/06 17:09
字数 3919
阅读 0
收藏 0

摘要: 仅用于记录R语言学习过程:

内容提要:

数据汇总统计有关的函数:apply家族(apply()、lappy()、sapply()、tapply()、mapply());ave()函数、by()函数、aggregate()函数、sweep()函数

数据预处理包:plyr包、dplyr包、data.table包

正文:

  数据汇总统计之apply家族

apply()函数:可用于矩阵,数组,数据框。参数设置:x=矩阵名,MARGIN 选1为对行操作,2为对列操作,fun为拟进行的函数运算,如sum,mean等

示例:

> mat <- matrix(1:24,nrow = 4,ncol = 6)

> apply(mat,1,sum)

[1] 66 72 78 84

lappy()函数:除了有汇总功能外,还有遍历的功能,返回的是列表

示例:lapply(X = c(1:5),FUN = log)     # 但此时的返回值是一个list

lapply(iris[,1:3],function(x)lm(x~iris$我,data = iris[,1:3]))

 

sapply()函数:返回的是向量、矩阵、数据框

示例:

> sapply(1:5,log)

[1] 0.0000000 0.6931472 1.0986123 1.3862944 1.6094379

> sapply(1:5,function(x) x+3)

[1] 4 5 6 7 8

tapply()函数:主要适用于数据框。根据一个分类变量将一个数值型变量进行切分,并且进行数据汇总。tapply只能对于一个变量进行汇总,如想同时对多个,可采用dcast()函数。

示例:tapply(iris$我,INDEX = iris$人,FUN = mean)

mapply()函数:使if语句具有向量化操作的功能

示例:

myfun <- funtion(x,y) {

  if(x >4) return(y)

  else return(x+y)

}

mapply(myfun,1:5,2:6)

  数据汇总函数

ave()函数:

示例:

survival <- data.frame(id =1:10,cancer=sample(c('lung','liver','colon'),

                                              10,replace = TRUE),

                       treatment = sample(c('Surg','Chemo'),10,replace = TRUE),

                       sur_days = sample(100:1000,10))

survival 

ave(survival$sur_days,survival$cancer)

其中ave函数中也可以自定义fun,如ave(survival$sur_days,survival$cancer,FUN = sd)

by()函数:可进行多个参数的汇总

示例:

> by(data = survival$sur_days,INDICES = survival$cancer,FUN =mean)

survival$cancer: colon

[1] 768

-----------------------------------------------------------------------------------------------------------------

survival$cancer: liver

[1] 387.6667

-----------------------------------------------------------------------------------------------------------------

survival$cancer: lung

[1] 772.5

u  示例2:

> by(data = survival$sur_days,INDICES = list(survival$cancer,survival$treatment)

+                                           ,FUN = mean)

: colon

: Chemo

[1] 931

-----------------------------------------------------------------------------------------------------------------

: liver

: Chemo

[1] 509.5

-----------------------------------------------------------------------------------------------------------------

: lung

: Chemo

[1] NA

-----------------------------------------------------------------------------------------------------------------

: colon

: Surg

[1] 605

-----------------------------------------------------------------------------------------------------------------

: liver

: Surg

[1] 326.75

-----------------------------------------------------------------------------------------------------------------

: lung

: Surg

[1] 772.5

u  示例3:自定义函数

by(mtcars,mtcars$cyl,function(x)lm(mpg~disp+hp,data = x))

aggregate()函数:功能特别强大,根据数据框原本的变量生成新的变量

示例1:

data(mtcars)

View(mtcars)

aggregate(x=mtcars,by =list(VS = mtcars$vs==1,high = mtcars$mpg >22),mean)

     VS  high      mpg      cyl     disp       hp     drat

1 FALSE FALSE 16.06471 7.647059 318.1412 195.5294 3.331176

TRUE FALSE 19.90000 5.333333 176.5500 111.1667 3.581667

3 FALSE  TRUE 26.00000 4.000000 120.3000  91.0000 4.430000

TRUE  TRUE 28.05000 4.000000  99.3875  76.5000 4.067500

        wt     qsec vs        am     gear     carb

1 3.779647 16.69353  0 0.2941176 3.470588 3.705882

2 3.133333 19.24500  1 0.1666667 3.500000 2.166667

3 2.140000 16.70000  0 1.0000000 5.000000 2.000000

4 2.219750 19.40000  1 0.7500000 4.125000 1.500000

示例2:做到了与dcast()函数相同的功能

aggregate(.~Species,data = iris,mean)  #除了Species外的所有iris数据集中的数据求均值。

sweep()函数:主要针对数组的,参数设置:STATS指的是统计量,FUN默认为减法,如果不是需要自己写入自定义的运算

示例:

> my_array <- array(1:24,dim= c(2,4,2))

> my_array

, , 1

 

     [,1] [,2] [,3] [,4]

[1,]    1    3    5    7

[2,]    2    4    6    8

 

, , 2

 

     [,1] [,2] [,3] [,4]

[1,]    9   11   13   15

[2,]   10   12   14   16

 

> sweep(x = my_array,MARGIN = 1,STATS = 1,FUN = '+')

, , 1

 

     [,1] [,2] [,3] [,4]

[1,]    2    4    6    8

[2,]    3    5    7    9

 

, , 2

 

     [,1] [,2] [,3] [,4]

[1,]   10   12   14   16

[2,]   11   13   15   17

 

  数据预处理包----plyr包

  • output

input

Array

Data frame

List

Discarded

Array

aaply

adply

alply

a_ply

Data frame

daply

ddply

dlply

d_ply

List

laply

ldply

llply

l_ply

 

aaply()函数

示例:

> my_matrix <- matrix(1:24,nrow = 3,ncol = 8)

> aaply(.data = my_matrix,.margins = 2,.fun = mean)

 1  2  3  4  5  6  7  8

 2  5  8  11 14 17 20 23    #返回的是数组

> apply(my_matrix,2,mean)

[1]  2  5  8 11 14 17 20 23   #返回的是向量

adply()函数

示例:

> adply(my_matrix,.margins =  2,.fun = mean)

  X1 V1            #返回的是数组

1  1  2

2  2  5

3  3  8

4  4 11

5  5 14

6  6 17

7  7 20

8  8 23

laply()函数:

示例

> my_list <- list(1:10,2:8,rep(c(T,F),times =5))

> laply(my_list,.fun = mean)

[1] 5.5 5.0 0.5

ddply()函数:可同时对一个对象进行多种数据汇总(如mean和sd);可根据多种分类变量对某一个数据框进行操作。

示例1:

> my_df <- data.frame(name = c('a','b','c','d','e'),

+                     height = c(178,176,175,167,190),

+                     gender = c('M','F','F','M','M'))

       > ddply(.data = my_df,.variables = .(gender),summarise,mean_h = mean(height))

  gender   mean_h

1      F 175.5000

2      M 178.3333

> ddply(.data = my_df,.variables = .(gender),summarise,mean_h = mean(height),sd_h = sd(height) )

  gender   mean_h       sd_h

1      F 175.5000  0.7071068

2      M 178.3333 11.5036226

> tapply(my_df$height,my_df$gender,mean)

       F        M

175.5000 178.3333

u  示例2:

my_df <- data.frame(name = c('a','b','c','d','e'),

                    height = c(178,176,175,167,190),

                    gender = c('M','F','F','M','M'),

                    age = c('old','young','old','old','young'))

> ddply(.data = my_df,.variables = .(gender,age),.fun = summarise,mean_h = mean(height))

  gender   age mean_h

1      F   old  175.0

2      F young  176.0

3      M   old  172.5

4      M young  190.0

u  示例3:自定义函数;多个分类变量的写法

library(reshape2)

View(tips)

tips

> ddply(tips, .(sex,smoker), function(x) sum(x$tip)/sum(x$total_bill))

     sex smoker        V1

1 Female     No 0.1531892

2 Female    Yes 0.1630623

3   Male     No 0.1573122

4   Male    Yes 0.1369188

> ddply(tips, ~ sex + smoker, function(x) sum(x$tip)/sum(x$total_bill))

     sex smoker        V1

1 Female     No 0.1531892

2 Female    Yes 0.1630623

3   Male     No 0.1573122

4   Male    Yes 0.1369188

u  三种写法求算平均值

ddply(iris,~Species,colwise(mean,c('Sepal.Length','Sepal.Width')))

 

ddply(iris,~Species,colwise(mean,.(Sepal.Length,Sepal.Width)))

 

ddply(iris,~Species,colwise(mean, ~ Sepal.Length + Sepal.Width))  #最推荐的,因为看着最简洁,不易错

dlply()函数:在进行回归分析的时候

示例:

my_model <- function(x) lm(Sepal.length ~ Sepal.Width,data = x)

dlply(iris,~$Species,my_model)

n  each()函数:对数据对象进行多批量的操作

u  示例:each(mean,sd,median)(iris$Sepal.length)  #一次性求出mean,sd和median

n  colwise()函数:表示对列进行操作

u  示例:colwise(mean)(iris)

n  numcolwise()函数:针对数据集中的数值型向量

u  示例:numcolwise(mean)(iris)

 

  数据预处理包----dplyr包

filter()函数:主要针对行的筛选函数

示例:

> sub1 <-filter(tips,tips$smoker == 'No',tips$day=='Sun')

> head(sub1)

  total_bill  tip    sex smoker day   time size

1      16.99 1.01 Female     No Sun Dinner    2

2      10.34 1.66   Male     No Sun Dinner    3

3      21.01 3.50   Male     No Sun Dinner    3

4      23.68 3.31   Male     No Sun Dinner    2

5      24.59 3.61 Female     No Sun Dinner    4

6      25.29 4.71   Male     No Sun Dinner    4

slice()函数:不对变量进行操作,只对行数进行操作。参数设置:数据集,选择的行数

示例:sub2 <- slice(tips,1:5)

select()函数:只要针对列进行操作。参数设置:数据集,想要显示的列名

示例:

sub3 <- select(tips, tip, sex, smoker)  #显示tips中的tip列,sex列和smoker列

sub4 <- select(tips, tip:time)   #显示tips集中从tip列到time列

sub4 <- select(tips,2:5)       #显示tips集的2到5 列

arrange()函数:排序。参数设置:数据集,拟用于排序的列名,可用desc()函数设置排序时降序排列,默认为升序排列。

示例:

> new_tips <- arrange(tips,total_bill,tip)

> head(new_tips)

  total_bill  tip    sex smoker  day   time size

1       3.07 1.00 Female    Yes  Sat Dinner    1

2       5.75 1.00 Female    Yes  Fri Dinner    2

3       7.25 1.00 Female     No  Sat Dinner    1

4       7.25 5.15   Male    Yes  Sun Dinner    2

5       7.51 2.00   Male     No Thur  Lunch    2

6       7.56 1.44   Male     No Thur  Lunch    2

> new_tips2 <- arrange(tips,desc(total_bill),tip)

> head(new_tips2)

  total_bill   tip    sex smoker day   time size

1      50.81 10.00   Male    Yes Sat Dinner    3

2      48.33  9.00   Male     No Sat Dinner    4

3      48.27  6.73   Male     No Sat Dinner    4

4      48.17  5.00   Male     No Sun Dinner    6

5      45.35  3.50   Male    Yes Sun Dinner    3

6      44.30  2.50 Female    Yes Sat Dinner    3

rename()函数:对列重新进行命名。参数设置:数据集,新名字=老名字,新名字=老名字。。。

示例:new_tips <- rename(tips, bill = total_bill, tipp =tip)

distinct()函数:返回因子水平,可以同时查看多列

示例:

> distinct(tips,sex)

     sex

1 Female

2   Male

> levels(tips$sex)

[1] "Female" "Male"

 

mutate()函数:用于生成新的变量,比较特别的地方在于可以在函数中用新生成的变量名作为另一个新变量生成中的一个变量。transform()函数则不能在rate后面再写上new_rate。

示例:new_tips3 <- mutate(tips,rate = tip/total_bill,new_rate = rate*100)

取随机数函数:sample_n()函数和sample_frac()函数:在数据框中随机抽取行。

参数设置:sample_n:数据对象,随机抽取的总行数,省略了抽取随机数的步骤

示例:sample_n(iris,size = 10)  #随机抽取iris中的10行

参数设置:sample_frac:数据对象,传入的比例

示例:sample_frac(iris,0.1)   #随机抽取iris中10%的行

分组函数:group_by(),一般结合summarise()函数一起使用

示例:

> group <- group_by(tips,smoker)

> summarise(group,count = n(),mean_tips = mean(tip),sd_bill = sd(total_bill))

# A tibble: 2 x 4

  smoker count mean_tips sd_bill

  <fct>  <int>     <dbl>   <dbl>

1 No       151      2.99    8.26

2 Yes       93      3.01    9.83

管道符: %>%,连通上下函数,可节省编程时间

示例:

> result <- tips %>% group_by(smoker,sex) %>% summarise(count = n(),mean_tips = mean(tip),sd_bill = sd(total_bill))

> result

# A tibble: 4 x 5

# Groups:   smoker [?]

  smoker sex    count mean_tips sd_bill

  <fct>  <fct>  <int>     <dbl>   <dbl>

1 No     Female    54      2.77    7.29

2 No     Male      97      3.11    8.73

3 Yes    Female    33      2.93    9.19

4 Yes    Male      60      3.05    9.91

join()函数家族:用于数据框的合并

inner_join()函数:合并,但只合并两个数据框里都有的

示例:

> df_a <- data.frame(x = c('a','b','c','a','c','b','c'),y =1:7)

> df_a

  x y

1 a 1

2 b 2

3 c 3

4 a 4

5 c 5

6 b 6

7 c 7

> df_b <- data.frame(x = c('a','b','a'),z = 10:12)

> df_b

  x  z

1 a 10

2 b 11

3 a 12

> inner_join(df_a,df_b,by = 'x')

  x y  z

1 a 1 10

2 a 1 12

3 b 2 11

4 a 4 10

5 a 4 12

6 b 6 11

semi_join()函数:如果第一个数据框的元素在第二个数据框里出现了,则返回第一个数据框的元素

示例:

> semi_join(df_a,df_b,by = 'x')

  x y

1 a 1

2 b 2

3 a 4

4 b 6

anti_join()函数:反结合,第二个数据框中的元素不出现的,第一个数据框中有的,则返回,如返回c(下例)

示例:

> anti_join(df_a,df_b,by = 'x')

  x y

1 c 3

2 c 5

3 c 7

left_join()函数:把所有元素结合到一起,没有都出现的用NA表示

示例:

> left_join(df_a,df_b,by = 'x')

  x y  z

1 a 1 10

2 a 1 12

3 b 2 11

4 c 3 NA

5 a 4 10

6 a 4 12

7 c 5 NA

8 b 6 11

9 c 7 NA

right_join()函数:根据第二个数据框进行填充,返回b中的所有行,三个列,如果a 中无b的观测,用NA填充。

示例:

> right_join(df_a,df_b,by = 'x')

  x y  z

1 a 1 10

2 a 4 10

3 b 2 11

4 b 6 11

5 a 1 12

6 a 4 12

  数据预处理包----data.table包

示例:

> library(data.table)

> dt <- data.table(v1=c(1,2),v2 = LETTERS[1:3],v3= rnorm(12,2,2),v4 = sample(1:20,12))

> dt

    v1 v2         v3 v4

 1:  1  A  1.0590425 13

 2:  2  B  0.4570105 14

 3:  1  C -0.2072561 11

 4:  2  A -0.4769700 17

 5:  1  B  0.9041292 15

 6:  2  C  1.2926636 19

 7:  1  A  1.9194111 20

 8:  2  B  4.3148126 18

 9:  1  C  0.5666122 12

10:  2  A  2.3982736  3

11:  1  B  2.6283114  2

12:  2  C  3.1367615  7

> dt[3:6,]    #提取行

   v1 v2         v3 v4

1:  1  C -0.2072561 11

2:  2  A -0.4769700 17

3:  1  B  0.9041292 15

4:  2  C  1.2926636 19

> dt[v2=='B']

   v1 v2        v3 v4

1:  2  B 0.4570105 14

2:  1  B 0.9041292 15

3:  2  B 4.3148126 18

4:  1  B 2.6283114  2

注1:rnorm()函数:生成正态分布的数据 rnorm(12,3,2)  12个数,均数为3,标准差为2

注2:round()函数,取整函数

注3:每一列中元素个数可不同,通过重复来进行填充

注4:可用[ ]来进行元素提取

%in%:判断变量v2是否在向量c(‘A’,’B’)当中,如果是,则返回A,B

示例:

> dt[v2 %in% c('A','B')]

   v1 v2         v3 v4

1:  1  A  1.0590425 13

2:  2  B  0.4570105 14

3:  2  A -0.4769700 17

4:  1  B  0.9041292 15

5:  1  A  1.9194111 20

6:  2  B  4.3148126 18

7:  2  A  2.3982736  3

8:  1  B  2.6283114  2

提取列:用[ ],但是只接受传入的为列名

示例:

> dt[,list(v1,v2)]

    v1 v2

 1:  1  A

 2:  2  B

 3:  1  C

 4:  2  A

 5:  1  B

 6:  2  C

 7:  1  A

 8:  2  B

 9:  1  C

10:  2  A

11:  1  B

12:  2  C

> dt[,v3]

      [1] -1  2  3  4  4  4  0  3  3  3  5  1

进行统计操作:如求和,均值,可多个操作,也可多个变量 并重新命名;前提是放到list里面去,也可以使用点.,来替代list

示例:

> dt[,sum(v4)]

[1] 114

> dt[,list(sum_v4 = sum(v4),mean_v4 = mean(v4))]

   sum_v4 mean_v4

1:    114     9.5

> dt[,list(sum_v3 = sum(v3),mean_v4 = mean(v4))]

   sum_v3 mean_v4

1:     31     9.5

生成新的变量

示例:

> dt[,list(v5 = v4+1,v6 = v3-1)]   #生成v5和v6

    v5 v6

 1: 20 -2

 2: 10  1

 3: 15  2

 4: 19  3

 5:  3  3

 6: 17  3

 7:  7 -1

 8:  8  2

 9: 16  2

10:  4  2

11:  5  4

12:  2  0

用于打印和作图:此时不能用list,要用{ },并且不同的命令之间要用分号;,用于分行

示例:

dt[,{print(v2);plot(1:12,v3,col = 'red')}]

[1] "A" "B" "C" "A" "B" "C" "A" "B" "C" "A" "B" "C"

NULL

图片未放置

by参数:根据by后面参数的水平,对by前面的数据进行操作

示例:

> dt[,list(sum_v3 = sum(v3)),by = v2 ]      #根据v2的水平对v3进行求和

   v2 sum_v3

1:  A      6

2:  B      5

3:  C     10

> dt[,list(sum_v3 = sum(v3),mean_v4 = mean(v4)),by = v2 ] #同时对v3和v4进行操作

   v2 sum_v3 mean_v4

1:  A      6    9.75

2:  B      5   10.75

3:  C     10    7.50

> dt[,list(sum_v3 = sum(v3),mean_v4 = mean(v4)),by = .(v2,v1)] #根据v2和v1进行v3和v4的操作  类似ddply 和summarise的联合操作

   v2 v1 sum_v3 mean_v4

1:  A  1      2    10.0

2:  B  2      2    17.0

3:  C  1      6     9.0

4:  A  2      4     9.5

5:  B  1      3     4.5

6:  C  2      4     6.0

> dt[1:8,list(sum_v3 = sum(v3),mean_v4 = mean(v4)),by = v2 ]  #仅对前8行进行相应操作

   v2 sum_v3   mean_v4

1:  A      5  7.333333

2:  B      0 11.666667

3:  C      3  8.000000

N参数:频数汇总  用法 .N,后面加上分类变量by

示例:

> dt[,.N,by =v2]  #注意:点号前面一定要写上逗号

   v2 N

1:  A 4

2:  B 4

3:  C 4

> dt[,.N,by = list(v1,v2)]  #根据v1和v2列出的频数

   v1 v2 N

1:  1  A 2

2:  2  B 2

3:  1  C 2

4:  2  A 2

5:  1  B 2

6:  2  C 2

:=(冒号等号) :这个符号的前后都需要有空格,用于把新的列加入到原来的变量dt中

示例:

> dt[,v5 := v4+1]

> dt

    v1 v2 v3 v4 v5

 1:  1  A  0  4  5

 2:  2  B  0 20 21

 3:  1  C  2 13 14

 4:  2  A  3  2  3

 5:  1  B -2  1  2

 6:  2  C  1  3  4

 7:  1  A  2 16 17

 8:  2  B  2 14 15

 9:  1  C  4  5  6

10:  2  A  1 17 18

11:  1  B  5  8  9

12:  2  C  3  9 10

 

> dt[,c('V5','V6') := list(v3 +1, v4-1)]  #加入多个列的写法

> dt

    v1 v2 v3 v4 v5 V5 V6

 1:  1  A  0  4  5  1  3

 2:  2  B  0 20 21  1 19

 3:  1  C  2 13 14  3 12

 4:  2  A  3  2  3  4  1

 5:  1  B -2  1  2 -1  0

 6:  2  C  1  3  4  2  2

 7:  1  A  2 16 17  3 15

 8:  2  B  2 14 15  3 13

 9:  1  C  4  5  6  5  4

10:  2  A  1 17 18  2 16

11:  1  B  5  8  9  6  7

12:  2  C  3  9 10  4  8

setkey()函数:设置关键变量

attach()函数:进入局部变量  如attach(iris)

setkey(dt,v2)  直接进入到v2,对v2进行操作

示例:

> setkey(dt,v2)

> dt[c('A','C')]

   v1 v2 v3 v4 v5 V5 V6

1:  1  A  0  4  5  1  3

2:  2  A  3  2  3  4  1

3:  1  A  2 16 17  3 15

4:  2  A  1 17 18  2 16

5:  1  C  2 13 14  3 12

6:  2  C  1  3  4  2  2

7:  1  C  4  5  6  5  4

8:  2  C  3  9 10  4  8

nomatch参数:没有匹配到,用NA表示

示例:

> dt[c('A','D'),nomatch = 0]   #设成0后就不返回NA

   v1 v2 v3 v4 v5 V5 V6

1:  1  A  0  4  5  1  3

2:  2  A  3  2  3  4  1

3:  1  A  2 16 17  3 15

4:  2  A  1 17 18  2 16

by = .EACHI 参数

示例:

> dt[c('A','B'),sum(v4),by = .EACHI]

   v2 V1

1:  A 39

2:  B 43

串联操作 :两个[ ]之间没有其他的符号

示例:

> dt[,.(v4_sum = sum(v4)), by = v2][v4_sum >40]

   v2 v4_sum

1:  B     43

 

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。

暂无文章

Python中的mkdir -p功能[重复] - mkdir -p functionality in Python [duplicate]

问题: This question already has an answer here: 这个问题在这里已有答案: How can I safely create a nested directory? 如何安全地创建嵌套目录? 25 answers 25个答案 Is there a way...

技术盛宴
今天
7
0
原价500元的认证证书,限时免费考取!

本文作者:y****n 百度云智学院致力于为百度ABC战略(人工智能、大数据、云计算)提供人才生态体系建设,包括基于百度ABC、IoT的课程体系,整合百度优势技术能力的深度学习技术、Apollo无人车...

百度开发者中心
昨天
9
0
在virtualenv中使用Python 3 - Using Python 3 in virtualenv

问题: Using virtualenv , I run my projects with the default version of Python (2.7). 使用virtualenv ,我使用默认版本的Python(2.7)运行项目。 On one project, I need to use Pyth......

富含淀粉
今天
16
0
Python的__init__和self是做什么的? - What __init__ and self do on Python?

问题: I'm learning the Python programming language and I've came across something I don't fully understand. 我正在学习Python编程语言,遇到了一些我不太了解的东西。 In a method ......

javail
今天
15
0
OSChina 周五乱弹 —— 你大妈还是你大妈

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @watergood:是时候分享一波我的这张纯音乐歌单了,过去的五年多时间里,我陆陆续续地把听到的好听的纯音乐添加了进去,目前一共65首,相信总...

小小编辑
今天
45
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部