# 2.1.4 数据框

    ##### 2.1 R中的数据类型 #####
    rm(list = ls())

    #### 2.1.4 数据框 ####
    ### 1.创建数据框 ###
    # 读入一个txt,csv等格式数据,即自成一个数据框
    movie = read.csv("电影数据.csv", fileEncoding = "UTF-8", stringsAsFactors = F)
    class(movie)
    ##  [1] "data.frame"

    # 自己创建
    star1 = c("邓超", "赵丽颖", "郭富城", "周润发", "杰克布莱克", "汤唯", "白敬亭", "陈晓", "梁家辉", "姚晨", "宋茜", "黄宗泽", "黄晓明")
    birthyear = c(1979, 1987, 1965, 1955, 1969, 1979, 1993, 1987, 1958, 1979, 1987, 1980, 1977)
    gender = c("男", "女", "男", "男", "男", "女", "男", "男", "男", "女", "女", "男", "男")
    stars = data.frame(star1, birthyear, gender); head(stars)
    ##         star1 birthyear gender
    ##  1       邓超      1979     男
    ##  2     赵丽颖      1987     女
    ##  3     郭富城      1965     男
    ##  4     周润发      1955     男
    ##  5 杰克布莱克      1969     男
    ##  6       汤唯      1979     女

    ### 2.汇总 ###
    str(movie)
    ##  'data.frame':   19 obs. of  11 variables:
    ##   $ name       : chr  "叶问3" "美人鱼" "女汉子真爱公式" "西游记之孙悟空三打白骨精" ...
    ##   $ boxoffice  : num  77060 338583 6184 119957 111694 ...
    ##   $ doubanscore: num  6.4 6.9 4.5 5.7 4 7.7 6.5 6.4 5 5.6 ...
    ##   $ type       : chr  "动作" "喜剧" "喜剧" "喜剧" ...
    ##   $ duration   : int  105 93 93 120 112 95 131 108 95 102 ...
    ##   $ showtime   : chr  "2016/3/4" "2016/2/8" "2016/3/18" "2016/2/8" ...
    ##   $ director   : chr  "叶伟信" "周星驰" "郭大雷" "郑保瑞" ...
    ##   $ star1      : chr  "甄子丹" "邓超" "赵丽颖" "郭富城" ...
    ##   $ index1     : int  11385 41310 181979 12227 16731 178 13499 14759 13251 6911 ...
    ##   $ star2      : chr  "张晋" "林允" "张翰" "巩俐" ...
    ##   $ index2     : int  4105 9292 44277 8546 30277 1540 77260 755 9549 5614 ...
    summary(movie)
    ##       name             boxoffice         doubanscore        type
    ##   Length:19          Min.   :   924.9   Min.   :3.400   Length:19
    ##   Class :character   1st Qu.:  3799.5   1st Qu.:4.600   Class :character
    ##   Mode  :character   Median : 12561.5   Median :5.300   Mode  :character
    ##                      Mean   : 50813.3   Mean   :5.568
    ##                      3rd Qu.: 77700.9   3rd Qu.:6.450
    ##                      Max.   :338583.3   Max.   :8.000
    ##      duration       showtime           director            star1
    ##   Min.   : 84.0   Length:19          Length:19          Length:19
    ##   1st Qu.: 94.5   Class :character   Class :character   Class :character
    ##   Median : 99.0   Mode  :character   Mode  :character   Mode  :character
    ##   Mean   :101.5
    ##   3rd Qu.:107.5
    ##   Max.   :131.0
    ##       index1          star2               index2
    ##   Min.   :   178   Length:19          Min.   :  521
    ##   1st Qu.:  8232   Class :character   1st Qu.: 3650
    ##   Median : 12227   Mode  :character   Median : 9292
    ##   Mean   : 27861                      Mean   :17369
    ##   3rd Qu.: 24663                      3rd Qu.:20763
    ##   Max.   :181979                      Max.   :77260
    head(movie)
    ##                        name boxoffice doubanscore type duration  showtime
    ##  1                    叶问3  77060.44         6.4 动作      105  2016/3/4
    ##  2                   美人鱼 338583.26         6.9 喜剧       93  2016/2/8
    ##  3           女汉子真爱公式   6184.45         4.5 喜剧       93 2016/3/18
    ##  4 西游记之孙悟空三打白骨精 119956.51         5.7 喜剧      120  2016/2/8
    ##  5               澳门风云三 111693.89         4.0 喜剧      112  2016/2/8
    ##  6                功夫熊猫3  99832.53         7.7 喜剧       95 2016/1/29
    ##    director      star1 index1        star2 index2
    ##  1   叶伟信     甄子丹  11385         张晋   4105
    ##  2   周星驰       邓超  41310         林允   9292
    ##  3   郭大雷     赵丽颖 181979         张翰  44277
    ##  4   郑保瑞     郭富城  12227         巩俐   8546
    ##  5     王晶     周润发  16731       刘德华  30277
    ##  6   吕寅荣 杰克布莱克    178 安吉丽娜朱莉   1540

    ### 3.变大--数据框的增列、合并 ###
    # 添加一列数据prefer
    prefer = 1:19
    movie$pre = prefer
    head(movie)
    ##                        name boxoffice doubanscore type duration  showtime
    ##  1                    叶问3  77060.44         6.4 动作      105  2016/3/4
    ##  2                   美人鱼 338583.26         6.9 喜剧       93  2016/2/8
    ##  3           女汉子真爱公式   6184.45         4.5 喜剧       93 2016/3/18
    ##  4 西游记之孙悟空三打白骨精 119956.51         5.7 喜剧      120  2016/2/8
    ##  5               澳门风云三 111693.89         4.0 喜剧      112  2016/2/8
    ##  6                功夫熊猫3  99832.53         7.7 喜剧       95 2016/1/29
    ##    director      star1 index1        star2 index2 pre
    ##  1   叶伟信     甄子丹  11385         张晋   4105   1
    ##  2   周星驰       邓超  41310         林允   9292   2
    ##  3   郭大雷     赵丽颖 181979         张翰  44277   3
    ##  4   郑保瑞     郭富城  12227         巩俐   8546   4
    ##  5     王晶     周润发  16731       刘德华  30277   5
    ##  6   吕寅荣 杰克布莱克    178 安吉丽娜朱莉   1540   6

    # merge实现的效果是：将movie和stars按照列star1匹配并合并起来
    (movie.star = merge(movie[1:3, ], stars,by = "star1"))
    ##     star1           name boxoffice doubanscore type duration  showtime
    ##  1   邓超         美人鱼 338583.26         6.9 喜剧       93  2016/2/8
    ##  2 赵丽颖 女汉子真爱公式   6184.45         4.5 喜剧       93 2016/3/18
    ##    director index1 star2 index2 pre birthyear gender
    ##  1   周星驰  41310  林允   9292   2      1979     男
    ##  2   郭大雷 181979  张翰  44277   3      1987     女
    # all.x=T,即取前一个数据框movie中star1列所有的值做合并，匹配不到赋值NA
    (movie.star = merge(movie[1:3, ], stars[1:5, ], by = "star1", all.x = T))
    ##     star1           name boxoffice doubanscore type duration  showtime
    ##  1   邓超         美人鱼 338583.26         6.9 喜剧       93  2016/2/8
    ##  2 赵丽颖 女汉子真爱公式   6184.45         4.5 喜剧       93 2016/3/18
    ##  3 甄子丹          叶问3  77060.44         6.4 动作      105  2016/3/4
    ##    director index1 star2 index2 pre birthyear gender
    ##  1   周星驰  41310  林允   9292   2      1979     男
    ##  2   郭大雷 181979  张翰  44277   3      1987     女
    ##  3   叶伟信  11385  张晋   4105   1        NA   <NA>

    ### 4.变小--数据的筛选、引用 ###
    # 引用
    movie[3, ]  # 查看第3行的电影信息
    ##              name boxoffice doubanscore type duration  showtime director
    ##  3 女汉子真爱公式   6184.45         4.5 喜剧       93 2016/3/18   郭大雷
    ##     star1 index1 star2 index2 pre
    ##  3 赵丽颖 181979  张翰  44277   3
    movie[, 8]  # 查看第8列主演者的名字
    ##   [1] "甄子丹"     "邓超"       "赵丽颖"     "郭富城"     "周润发"
    ##   [6] "杰克布莱克" "汤唯"       "白敬亭"     "陈晓"       "梁家辉"
    ##  [11] "姚晨"       "宋茜"       "黄宗泽"     "黄晓明"     "洪金宝"
    ##  [16] "陈坤"       "陶泽如"     "刘亦菲"     "何润东"
    # 筛选
    movie$star1  # 用$符号通过列名引用
    ##   [1] "甄子丹"     "邓超"       "赵丽颖"     "郭富城"     "周润发"
    ##   [6] "杰克布莱克" "汤唯"       "白敬亭"     "陈晓"       "梁家辉"
    ##  [11] "姚晨"       "宋茜"       "黄宗泽"     "黄晓明"     "洪金宝"
    ##  [16] "陈坤"       "陶泽如"     "刘亦菲"     "何润东"
    (action = movie[movie$type == "动作", ])  # 选择数据中的动作电影
    ##             name boxoffice doubanscore type duration  showtime director
    ##  1         叶问3  77060.44         6.4 动作      105  2016/3/4   叶伟信
    ##  10     冰河追凶   4262.14         5.6 动作      102 2016/4/15     徐伟
    ##  15 我的特工爷爷  32009.37         5.3 动作       99  2016/4/1   洪金宝
    ##  19         钢刀    924.86         4.3 动作       94 2016/5/20     阿甘
    ##      star1 index1  star2 index2 pre
    ##  1  甄子丹  11385   张晋   4105   1
    ##  10 梁家辉   6911 佟大为   5614  10
    ##  15 洪金宝   9148 刘德华  30277  15
    ##  19 何润东  11822 李学东    521  19
    (action_long = movie[movie$type == "动作" & movie$duration > 100, ])  # 放映时间超过100分钟的动作电影
    ##         name boxoffice doubanscore type duration  showtime director  star1
    ##  1     叶问3  77060.44         6.4 动作      105  2016/3/4   叶伟信 甄子丹
    ##  10 冰河追凶   4262.14         5.6 动作      102 2016/4/15     徐伟 梁家辉
    ##     index1  star2 index2 pre
    ##  1   11385   张晋   4105   1
    ##  10   6911 佟大为   5614  10

    ### 5.变序--数据框的内部排序 ###
    # 按照票房降序排列
    movie = movie[order(movie$boxoffice, decreasing = T), ]; head(movie)
    ##                        name boxoffice doubanscore type duration  showtime
    ##  2                   美人鱼 338583.26         6.9 喜剧       93  2016/2/8
    ##  4 西游记之孙悟空三打白骨精 119956.51         5.7 喜剧      120  2016/2/8
    ##  5               澳门风云三 111693.89         4.0 喜剧      112  2016/2/8
    ##  6                功夫熊猫3  99832.53         7.7 喜剧       95 2016/1/29
    ##  7 北京遇上西雅图之不二情书  78341.38         6.5 喜剧      131 2016/4/29
    ##  1                    叶问3  77060.44         6.4 动作      105  2016/3/4
    ##    director      star1 index1        star2 index2 pre
    ##  2   周星驰       邓超  41310         林允   9292   2
    ##  4   郑保瑞     郭富城  12227         巩俐   8546   4
    ##  5     王晶     周润发  16731       刘德华  30277   5
    ##  6   吕寅荣 杰克布莱克    178 安吉丽娜朱莉   1540   6
    ##  7   薛晓路       汤唯  13499       吴秀波  77260   7
    ##  1   叶伟信     甄子丹  11385         张晋   4105   1
    # 先按电影类型排序，再按照豆瓣评分排序
    movie = movie[order(movie$type, movie$doubanscore, decreasing = T), ]; head(movie)
    ##                         name boxoffice doubanscore type duration  showtime
    ##  6                 功夫熊猫3  99832.53         7.7 喜剧       95 2016/1/29
    ##  2                    美人鱼 338583.26         6.9 喜剧       93  2016/2/8
    ##  7  北京遇上西雅图之不二情书  78341.38         6.5 喜剧      131 2016/4/29
    ##  4  西游记之孙悟空三打白骨精 119956.51         5.7 喜剧      120  2016/2/8
    ##  13                 刑警兄弟   3005.96         5.2 喜剧       97 2016/4/22
    ##  3            女汉子真爱公式   6184.45         4.5 喜剧       93 2016/3/18
    ##     director      star1 index1        star2 index2 pre
    ##  6    吕寅荣 杰克布莱克    178 安吉丽娜朱莉   1540   6
    ##  2    周星驰       邓超  41310         林允   9292   2
    ##  7    薛晓路       汤唯  13499       吴秀波  77260   7
    ##  4    郑保瑞     郭富城  12227         巩俐   8546   4
    ##  13   戚家基     黄宗泽   9823         金刚   4010  13
    ##  3    郭大雷     赵丽颖 181979         张翰  44277   3

    ### 6.变形--长宽表互换 ###
    # install.packages(reshape)
    library(reshape)
    # install.packages(reshape2)
    library(reshape2)
    ## (1) 宽表变长表 ##
    mWide = data.frame(Name = c("熊大", "水妈"), Type = c("帅哥", "美女"),
                       GF2013 = c(300, 100), GF2014 = c(500, 350), GF2015 = c(1000, 886))
                       # 由于构造数据框时列名不可以为纯数字，在数字前添加GF
    # 将列名中的GF去掉
    colnames(mWide)[3:5] = gsub("GF", "", colnames(mWide)[3:5])
    mWide #查看原表
    ##    Name Type 2013 2014 2015
    ##  1 熊大 帅哥  300  500 1000
    ##  2 水妈 美女  100  350  886
    (mLong = melt(mWide, id.vars = c("Name", "Type"), variable_name = "Year"))
    ##    Name Type Year value
    ##  1 熊大 帅哥 2013   300
    ##  2 水妈 美女 2013   100
    ##  3 熊大 帅哥 2014   500
    ##  4 水妈 美女 2014   350
    ##  5 熊大 帅哥 2015  1000
    ##  6 水妈 美女 2015   886
    ## (2) 长表变宽表 ##
    # 将列Year从字符型变成数值型
    mLong$Year = as.numeric(mLong$Year)

    # 长表变宽表
    dcast(mLong, Name + Type ~ Year)
    ##    Name Type   1   2    3
    ##  1 水妈 美女 100 350  886
    ##  2 熊大 帅哥 300 500 1000

    ### 7.R中的数据透视表-神奇的ddply ###
    # install.packages(plyr)
    library(plyr)
    # 根据电影类型进行分组，查看不同类型电影票房的平均水平
    popular_type = ddply(movie, .(type), function(x) {mean(x$boxoffice)}); head(popular_type)
    ##    type       V1
    ##  1 爱情 11206.95
    ##  2 动作 28564.20
    ##  3 犯罪 36624.84
    ##  4 剧情  6671.91
    ##  5 喜剧 95116.85
    # 根据电影类型和电影时长同时分组，查看电影票房的平均水平
    long = ddply(movie, .(type,duration), function(x) {mean(x$index1)}); head(long)
    ##    type duration    V1
    ##  1 爱情       84 58355
    ##  2 爱情       95 13251
    ##  3 爱情      108 14759
    ##  4 动作       94 11822
    ##  5 动作       99  9148
    ##  6 动作      102  6911