R语言学习笔记(13)-数据转换

参考:(34-37)
https://www.bilibili.com/video/BV19x411X7C6?p=34

核心内容

数据转换(一)

视频里用到的扩展包是xlsx,但是需要Java环境。所以我下的是openxlsx包

> install.packages("openxlsx")

is判断函数类型
is.data.frame() 判断是否为数据框
is.na是否包含缺失后置

as()函数对数据进行强制转换

#矩阵→数据框,较容易
> is.data.frame(state.x77)
[1] FALSE
> dstate <- as.data.frame(state.x77)
> is.data.frame(dstate)
[1] TRUE
#数据框→矩阵
> data.frame(state.region,state.x77)
> as.matrix(data.frame(state.region,state.x77))
#里面所有内容都变为字符型
#查看所有is/as函数
>methods(is)

向量→多种类型

> x <- state.abb
> x
 [1] "AL" "AK" "AZ" "AR" "CA" "CO" "CT" "DE" "FL" "GA" "HI" "ID" "IL" "IN" "IA" "KS"
[17] "KY" "LA" "ME" "MD" "MA" "MI" "MN" "MS" "MO" "MT" "NE" "NV" "NH" "NJ" "NM" "NY"
[33] "NC" "ND" "OH" "OK" "OR" "PA" "RI" "SC" "SD" "TN" "TX" "UT" "VT" "VA" "WA" "WV"
[49] "WI" "WY"
#添加维度便变为数组
> dim(x) <- c(5,10)
> x
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] "AL" "CO" "HI" "KS" "MA" "MT" "NM" "OK" "SD" "VA" 
[2,] "AK" "CT" "ID" "KY" "MI" "NE" "NY" "OR" "TN" "WA" 
[3,] "AZ" "DE" "IL" "LA" "MN" "NV" "NC" "PA" "TX" "WV" 
[4,] "AR" "FL" "IN" "ME" "MS" "NH" "ND" "RI" "UT" "WI" 
[5,] "CA" "GA" "IA" "MD" "MO" "NJ" "OH" "SC" "VT" "WY" 
> x <- state.abb
#转换为因子
> as.factor(x)
 [1] AL AK AZ AR CA CO CT DE FL GA HI ID IL IN IA KS KY LA ME MD MA MI MN MS MO MT NE
[28] NV NH NJ NM NY NC ND OH OK OR PA RI SC SD TN TX UT VT VA WA WV WI WY
50 Levels: AK AL AR AZ CA CO CT DE FL GA HI IA ID IL IN KS KY LA MA MD ME MI ... WY
#转换为list列表
> as.list(x)
[[1]]
[1] "AL"

[[2]]
[1] "AK"

[[3]]
[1] "AZ"

[[4]]
[1] "AR"

[[5]]
[1] "CA"

[[6]]
[1] "CO"

[[7]]
[1] "CT"

[[8]]
[1] "DE"

[[9]]
[1] "FL"

[[10]]
[1] "GA"

[[11]]
[1] "HI"

[[12]]
[1] "ID"

[[13]]
[1] "IL"

[[14]]
[1] "IN"

[[15]]
[1] "IA"

[[16]]
[1] "KS"

[[17]]
[1] "KY"

[[18]]
[1] "LA"

[[19]]
[1] "ME"

[[20]]
[1] "MD"

[[21]]
[1] "MA"

[[22]]
[1] "MI"

[[23]]
[1] "MN"

[[24]]
[1] "MS"

[[25]]
[1] "MO"

[[26]]
[1] "MT"

[[27]]
[1] "NE"

[[28]]
[1] "NV"

[[29]]
[1] "NH"

[[30]]
[1] "NJ"

[[31]]
[1] "NM"

[[32]]
[1] "NY"

[[33]]
[1] "NC"

[[34]]
[1] "ND"

[[35]]
[1] "OH"

[[36]]
[1] "OK"

[[37]]
[1] "OR"

[[38]]
[1] "PA"

[[39]]
[1] "RI"

[[40]]
[1] "SC"

[[41]]
[1] "SD"

[[42]]
[1] "TN"

[[43]]
[1] "TX"

[[44]]
[1] "UT"

[[45]]
[1] "VT"

[[46]]
[1] "VA"

[[47]]
[1] "WA"

[[48]]
[1] "WV"

[[49]]
[1] "WI"

[[50]]
[1] "WY"
#加上另外两个转换为数据框
> state <- data.frame(x,state.region,state.x77)
> y <- state["Neveda",]
> y
#去除列名
> uname(y)
#转换为向量
> unlist(y)

数据转换(二)

  1. 对数据取子集
#主义先看该文件是否在当前工作路径下
> who <- read.csv("WHO.csv",header = T)
#提取1-50行,1-10列数据
> who1 <- who[c(1,50),c(1:10)]
#提取1,3,5,8行;2,14,16,18列
> who2 <- who[c(1,3,5,8),c(2,14,16,18)]
#使用逻辑值进行筛选,如which函数判断
> who3 <- who[which(who$Continent == 7),]
> who4 <- who[which(who$CountryID >50 & who$CountryID <= 100)]
#直接使用subset()
> who4 <- subset(who,who$CountryID >50 & who$CountryID <= 100))
  1. 抽样
    (1)sample抽取向量
> x <- 1:100
#默认为无返回抽样,即每个数据仅出现一次
> sample(x,30)
#设置replace = T
> sample(x,60,replace = T)
 [1] 86 26  5 33 65 47 58 90 85 76 27 90 40 93 38 14 16 97 32 34 49 92  3 17 16 88 13
[28] 24 57 81 71 27 84 21 29 29 27 39 93 83 76  8 97 68 26 16 66 30 22 69 20 15 90 57
[55]  7  5 18 83 64 48
#sort排序一下,可以看出是有重复的抽样
> sort(sample(x,60,replace = T))
[1]   1   3   3   3   4   6   8  10  12  14  14  15  17  17  19  24  28  31  32  34
[21]  35  36  36  37  40  41  41  42  44  45  45  47  50  51  52  54  58  59  62  63
[41]  63  64  65  66  67  73  73  74  75  75  75  78  82  82  84  86  87  91  98 100

(2)sample对数据框抽样

> sample(who$CountryID,30,replace = F)
>who[sample(who$CountryID,30,replace = F),]
  1. 删除固定行数据
    (1)最简单:负索引
#逗号在后,删除对应列
> mtcars[-1:-5,]
#逗号在前,删除对应行
> mtcars[,-1:-5]

(2)赋值为NULL

#删除对应列
> mtcats$mpg <- NULL
#但给行删除较为麻烦
  1. 数据框添加与合并
    (1)data.frame()生成新数据框
> data.frame(USArrests,state.division)

(2)列cbind(),行rbind()

cbind(USArrests,state.division)
#合并行较为麻烦,需要新的数据与原来的数据具有相同的列名,否则无法合并
> data1 <- head(USArrests,20)
> data2 <- tail(USArrests,20)
> rbind(data1,data2)

还可用于矩阵类型
使用cbind()和rbind()时,要求有相同的行数或列数
例如

> head(cbind(USArrests,state.division),20)
>data3 <- head(cbind(USArrests,state.division),20)
> rbind(data2,data3)
Error in rbind(deparse.level, ...) : 变量的列数不对
  1. 删除重复行
    (1)duplicated()
#将data1和data2各取30行数据,则各自有10行重复数据
> data1 <- head(USArrests,30)
> data2 <- tail(USArrests,30)
#合并看看会有什么问题
> data4 <- rbind(data1,data2)
> rownames(data4)
> length(rownames(data4))
[1] 60//说明是完整合并,没有去除重复项

Excel中有删除重复项的功能
R中也可,需要取子集,获得一个没有重复项行名的一个向量集合,根据这个ID索引数据。

#duplicated()查看重复值,返回TRUE或FALSE
> duplicated(data4)
> data4[duplicated(data4),]
#R会默认将重复项添加一个1
#去除非重复部分,感叹号取反
> data4[!duplicated(data4),]
> length(data4(!duplicated(data4),))
[1] 4
> length(rownames(data4(!duplicated(data4),)))
[1] 50

(2)unique()

> unique(data4)
> length(unique(data4))
[1] 50

数据转换(三)

  1. 数据框翻转,调换行和列
    (1)Excel中
    选中所有行和列-复制-在新的sheet中,按Ctrl+Alt+v进行选择性复制-选择“转置”
    (2)R中
#整个进行翻转
> sractm <- t(mtcars)
#单独行和列进行翻转rev()
> ?rev
#翻转向量
> letters
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t"
[21] "u" "v" "w" "x" "y" "z"
> rev(letters)
 [1] "z" "y" "x" "w" "v" "u" "t" "s" "r" "q" "p" "o" "n" "m" "l" "k" "j" "i" "h" "g"
[21] "f" "e" "d" "c" "b" "a"
#翻转数据框
> women
   height weight
1      58    115
2      59    117
3      60    120
4      61    123
5      62    126
6      63    129
7      64    132
8      65    135
9      66    139
10     67    142
11     68    146
12     69    150
13     70    154
14     71    159
15     72    164
#根据行名进行数据翻转
> rownames(women)
 [1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10" "11" "12" "13" "14" "15"
> rev(rownames(women))
 [1] "15" "14" "13" "12" "11" "10" "9"  "8"  "7"  "6"  "5"  "4"  "3"  "2"  "1" 
#将翻转好的行名进行索引,访问数据
> women[rev(rownames(women)),]
   height weight
15     72    164
14     71    159
13     70    154
12     69    150
11     68    146
10     67    142
9      66    139
8      65    135
7      64    132
6      63    129
5      62    126
4      61    123
3      60    120
2      59    117
1      58    115
  1. 修改数据框的值
    (1)
#将women中的height从英寸转换为以厘米为单位,需要×2.54
> women$height*2.54
 [1] 147.32 149.86 152.40 154.94 157.48 160.02 162.56 165.10 167.64 170.18 172.72
[12] 175.26 177.80 180.34 182.88
> data.frame(women$height*2.54,women$weight)
   women.height...2.54 women.weight
1               147.32          115
2               149.86          117
3               152.40          120
4               154.94          123
5               157.48          126
6               160.02          129
7               162.56          132
8               165.10          135
9               167.64          139
10              170.18          142
11              172.72          146
12              175.26          150
13              177.80          154
14              180.34          159
15              182.88          164

但是这种方法并不高效
(2)transform()

> > transform(women,height=height*2.54)
   height weight
1  147.32    115
2  149.86    117
3  152.40    120
4  154.94    123
5  157.48    126
6  160.02    129
7  162.56    132
8  165.10    135
9  167.64    139
10 170.18    142
11 172.72    146
12 175.26    150
13 177.80    154
14 180.34    159
15 182.88    164
> transform(women,cm=height*2.54)
   height weight     cm
1      58    115 147.32
2      59    117 149.86
3      60    120 152.40
4      61    123 154.94
5      62    126 157.48
6      63    129 160.02
7      64    132 162.56
8      65    135 165.10
9      66    139 167.64
10     67    142 170.18
11     68    146 172.72
12     69    150 175.26
13     70    154 177.80
14     71    159 180.34
15     72    164 182.88
  1. 数据框的排序
    (1)sort():对向量进行排序,返回值是排序后的结果向量
    默认是从小到大的顺序。
    配合rev()函数,则是按相反顺序进行排序。
    不能直接用于数据框的排序
    但可以对数据框中行和列进行单独排序,然后通过对索引的访问,达到对整个数据框排序的效果
> mtcars[sort(rownames(mtcars)),]

(2)order():对向量进行排序,返回的值是向量的位置

> sort(rivers)
  [1]  135  202  210  210  215  217  230  230  233  237  246  250  250  250  255  259
 [17]  260  260  265  268  270  276  280  280  280  281  286  290  291  300  300  300
 [33]  301  306  310  310  314  315  320  325  327  329  330  332  336  338  340  350
 [49]  350  350  350  352  360  360  360  360  375  377  380  380  383  390  390  392
 [65]  407  410  411  420  420  424  425  430  431  435  444  445  450  460  460  465
 [81]  470  490  500  500  505  524  525  525  529  538  540  545  560  570  600  600
 [97]  600  605  610  618  620  625  630  652  671  680  696  710  720  720  730  735
[113]  735  760  780  800  840  850  870  890  900  900  906  981 1000 1038 1054 1100
[129] 1171 1205 1243 1270 1306 1450 1459 1770 1885 2315 2348 2533 3710
> order(rivers)
  [1]   8  17  39 108 129  52  36  42  91 117 133  34  56  87  76  55  41  75  37 127
 [21] 138 107  13  30  72  53  29  19  49  61 103 124 126  46  94 123 116  14   2   3
 [41]  35  18  11  65  12  81  51  27  60  78 111  54  43 112 119 134  97 105 102 104
 [61]  96  33  47   4  28  73  88  48 110 122 106 139  77  92 125 100   6  74  95   9
 [81]  57  93  84 136  22   5  31 132 135 113 120  99  62  59  10  21  45  86 118  80
[101] 128  64  40 130 140  58  85  50  32 137  44   1  90  79  71 109  24  38  15  26
[121]  63 131  16  82  20 121  89 114  67 115  25  98  83  23   7 141 101  69  66  70
[141]  68

好处:索引值可以直接用来访问数据框,就可以间接对数据框进行排序

> mtcars[order(mtcars$mpg),]
#按相反顺序排列,在其前面加减号
> mtcars[order(-mtcars$mpg),]

(3)rank():求秩,返回值是这个向量对元素的排名,较复杂,暂时放一边~

R还可以对多个条件进行排序

> mtcars[order(mtcars$mpg,mtcars$disp),]

数据转换(四)

1.对数据框进行计算
worldphones:全球八个区域七年中的电话数量的数据集
想知道每一年总的电话数量,以及七年间平均每个大洲的电话数量
(一)Excel中,使用average函数
(二)R中
(1)
rowSums():计算每一年的综述
colMeans():计算每个大洲的平均数

> rs <- rowSums(WorldPhones)
> rs
  1951   1956   1957   1958   1959   1960   1961 
 74494 102199 110001 118399 124801 133709 141700 
> cm <- colMeans(WorldPhones)
> cm
    N.Amer     Europe       Asia     S.Amer    Oceania     Africa   Mid.Amer 
66747.5714 34343.4286  6229.2857  2772.2857  2625.0000  1484.0000   841.7143 
#接下来使用cbind()添加为最后一列
> total <- cbind(WorldPhones,total = rs)
> total <- cbind(WorldPhones,total = rs)
> total
     N.Amer Europe Asia S.Amer Oceania Africa Mid.Amer  total
1951  45939  21574 2876   1815    1646     89      555  74494
1956  60423  29990 4708   2568    2366   1411      733 102199
1957  64721  32510 5230   2695    2526   1546      773 110001
1958  68484  35218 6662   2845    2691   1663      836 118399
1959  71799  37598 6856   3000    2868   1769      911 124801
1960  76036  40341 8220   3145    3054   1905     1008 133709
1961  79831  43173 9053   3338    3224   2005     1076 141700
#使用rbind()将平均值添加到最后一行
> mean <- cbind(total, mean = cm)
> mean
     N.Amer Europe Asia S.Amer Oceania Africa Mid.Amer  total       mean
1951  45939  21574 2876   1815    1646     89      555  74494 66747.5714
1956  60423  29990 4708   2568    2366   1411      733 102199 34343.4286
1957  64721  32510 5230   2695    2526   1546      773 110001  6229.2857
1958  68484  35218 6662   2845    2691   1663      836 118399  2772.2857
1959  71799  37598 6856   3000    2868   1769      911 124801  2625.0000
1960  76036  40341 8220   3145    3054   1905     1008 133709  1484.0000
1961  79831  43173 9053   3338    3224   2005     1076 141700   841.7143

(2)
但是total下面的平均值并不是这一列的均值
R中有apply()函数可以解决


apply.png
#对每一行进行求和,故MARGIN值为1,FUN参数设置为sum
> apply(WorldPhones,MARGIN = 1,FUN = sum)
#对每一列求平均值
> apply(WorldPhones,MARGIN = 2, FUN = mean)
#FUN还可以设置为求方差,求对数等等

(3)与apply类似,但返回值不同
lapply():listapply,返回值是列表形式
sapply():simplify,简化,返回值是向量或矩阵
state.center为列表数据集

> lapply(state.center, FUN = length)
$x
[1] 50

$y
[1] 50
> sapply(state.center,FUN = length)//返回值为向量
 x  y 
50 50 

tapply():处理因子数据,根据因子来分组,然后对每一组分别处理
参数:x,INDEX(必须为因子),FUN

#计算每个区包含几个洲
> tapply(state.name,state.division, FUN = length)
       New England    Middle Atlantic     South Atlantic East South Central 
                 6                  3                  8                  4 
West South Central East North Central West North Central           Mountain 
                 4                  5                  7                  8 
           Pacific 
                 5 

还有eapply,rapply等
强大之处在于:FUN这个参数,可以调用各种不同的函数,需要在以后学习中多积累。

  1. R中数据的中心化与标准化

数据中心化,是指数据集中各项数据减去数据集的均值。
数据标准化,是指在中心化之后再除以数据集的标准差,即数据集中的各项数据减去数据集的均值再除以数据集的标准差。

意义:消除量纲对数据结构的影响,处理之后使数据向中心靠拢,让数据集整个之间的差别更小
例如:
state.x77,各项数据之间差距太大,绘制热图可能没什么意义


heatmap(state.x77).png

这就需要进行数据中心化和标准化处理,要对每一列进行等比例缩小。例如面积一列减去平均值
(1) 简单实例

> x <- c(1,2,3,6,3)
> mean(x)
[1] 3
#中心化处理,每个值减去3
> x-mean(x)
#标准化处理
> sd(x)
[1] 1.870829
> (x-mean(x))/sd(x)
[1] -1.0690450 -0.5345225  0.0000000  1.6035675  0.0000000

(2)scale()
参数:x,center(中心化处理),scale(标准化处理)

> x <- scale(state.x77,center = T,scale = T)
> head(x)
           Population     Income Illiteracy   Life Exp     Murder    HS Grad
Alabama    -0.1414316 -1.3211387   1.525758 -1.3621937  2.0918101 -1.4619293
Alaska     -0.8693980  3.0582456   0.541398 -1.1685098  1.0624293  1.6828035
Arizona    -0.4556891  0.1533029   1.033578 -0.2447866  0.1143154  0.6180514
Arkansas   -0.4785360 -1.7214837   1.197638 -0.1628435  0.7373617 -1.6352611
California  3.7969790  1.1037155  -0.114842  0.6193415  0.7915396  1.1751891
Colorado   -0.3819965  0.7294092  -0.771082  0.8800698 -0.1565742  1.3361400
                Frost       Area
Alabama    -1.6248292 -0.2347183
Alaska      0.9145676  5.8093497
Arizona    -1.7210185  0.5002047
Arkansas   -0.7591257 -0.2202212
California -1.6248292  1.0034903
Colorado    1.1838976  0.3870991
> head(state.x77)
           Population Income Illiteracy Life Exp Murder HS Grad Frost   Area
Alabama          3615   3624        2.1    69.05   15.1    41.3    20  50708
Alaska            365   6315        1.5    69.31   11.3    66.7   152 566432
Arizona          2212   4530        1.8    70.55    7.8    58.1    15 113417
Arkansas         2110   3378        1.9    70.66   10.1    39.9    65  51945
California      21198   5114        1.1    71.71   10.3    62.6    20 156361
Colorado         2541   4884        0.7    72.06    6.8    63.9   166 103766
> heatmap(x)
heatmap(state.x77)centerscale.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容