美文网首页R语言学习R for statisticsR
R语言学习笔记(13)-数据转换

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

作者: Akuooo | 来源:发表于2021-01-25 21:57 被阅读0次

    参考:(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

    相关文章

      网友评论

        本文标题:R语言学习笔记(13)-数据转换

        本文链接:https://www.haomeiwen.com/subject/pywmzktx.html