dataframe 转置函数

在R中提供了t()函数用来进行转置,很多时候确实提供了诸多便利,但是由于t()函数在转置时会强制把data.frame函数转换成matrix格式,在后续的计算中又带来麻烦。由于在平时的计算中会经常用到转置,为了节省时间,把data.frame格式转置的一系列操作打包成函数备份,方便以后使用。

使用的包和数据

由于在平时的计算中会经常用到data.table()包,所以这里的dataframe转置函数默认已经载入此包。这里我们使用中国北京市的一组经济数据,具体如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
library(data.table)
> tdata
V1 20152014201320122011201020092008200720062005
1: 地区生产总值(亿元) 23014.59 21330.83 19800.81 17879.40 16251.93 14113.58 12153.03 11115.00 9846.81 8117.78 6969.52
2: 第一产业增加值(亿元) 140.21 158.99 159.64 150.20 136.27 124.36 118.29 112.83 101.26 88.80 88.68
3: 第二产业增加值(亿元) 4542.64 4544.80 4292.56 4059.27 3752.48 3388.38 2855.55 2626.41 2509.40 2191.43 2026.51
4: 第三产业增加值(亿元) 18331.74 16627.04 15348.61 13669.93 12363.18 10600.84 9179.19 8375.76 7236.15 5837.55 4854.33
5: 农林牧渔业增加值(亿元) 142.60 161.32 161.83 150.20 136.27 124.36 118.29 112.83 101.26 88.80 88.68
6: 工业增加值(亿元) 3710.88 3746.77 3566.43 3294.32 3048.79 2763.99 2303.08 2131.75 2082.76 1821.86 1707.04
7: 建筑业增加值(亿元) 961.86 902.66 831.55 764.95 703.69 624.39 552.47 494.66 426.64 369.57 319.47
8: 批发和零售业增加值(亿元) 2352.34 2411.14 2340.74 2229.77 2139.65 1888.51 1525.03 1426.72 1098.23 871.96 704.28
9: 批发和零售贸易餐饮业增加值(亿元) 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
10: 交通运输、仓储和邮政业增加值(亿元) 983.87 948.10 871.76 816.31 808.95 712.01 556.64 498.92 497.55 455.21 403.32
11: 交通运输、仓储和邮电通信业增加值(亿元) 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
12: 住宿和餐饮业增加值(亿元) 397.59 363.76 374.75 373.06 348.42 317.34 262.51 274.43 244.96 218.39 182.30
13: 金融业增加值(亿元) 3926.28 3357.71 2943.13 2536.91 2215.41 1863.61 1603.63 1519.19 1302.77 982.37 840.20
14: 房地产业增加值(亿元) 1438.43 1329.20 1339.52 1244.17 1074.93 1006.52 1062.47 844.59 821.50 658.30 493.73
15: 其他行业增加值(亿元) 9100.73 8110.18 7371.10 6469.71 5775.82 4812.85 4168.91 3811.91 3271.14 2651.32 2230.50
16: 人均地区生产总值(元/人) 106497.00 99995.00 94647.88 87474.74 81658.00 73856.00 66940.00 64491.00 60096.00 49505.00 45443.69
200420032002200120001999199819971996
1: 6033.21 5007.21 4315.00 3707.96 3161.66 2678.82 2377.18 2077.09 1789.20
2: 87.36 84.11 82.44 80.78 79.25 78.35 77.86 77.18 73.36
3: 1853.58 1487.15 1249.99 1142.35 1033.29 907.34 840.57 781.85 714.65
4: 4092.27 3435.95 2982.57 2484.83 2049.12 1693.13 1458.75 1218.06 1001.19
5: 87.36 84.11 82.44 80.78 79.25 78.35 77.86 77.18 73.36
6: 1554.73 1224.48 1021.16 938.81 844.01 723.98 670.36 635.91 576.14
7: 298.85 262.67 228.83 203.54 189.28 183.36 170.21 145.94 138.51
8: 587.70 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
9: 0.00 567.09 509.68 459.11 406.38 364.46 331.84 299.74 257.78
10: 356.78 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
11: 0.00 463.39 408.41 360.89 298.67 249.74 217.97 182.77 145.86
12: 163.30 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
13: 713.79 635.56 561.91 487.54 425.19 356.85 307.38 268.14 194.71
14: 436.11 341.88 298.02 203.55 144.01 105.55 75.32 48.21 34.63
15: 1834.59 1428.03 1204.55 973.74 774.87 616.53 526.24 419.20 368.21
16: 41099.00 34892.00 30840.00 26998.00 24122.00 21407.00 19128.00 16621.00 14254.00

处理思路

  1. ​首先提取原数据集除去首列的所有列名。
  2. ​转置原数据集,保存为tempdata,此时的格式为matrix格式。
  3. 提取tempdata的第一行。
  4. tempdata去除第一行的数据转化为data.table格式。
  5. 把提取到的tempdata第一行作为列名赋值给data.table格式的tempdata
  6. 把提取到原数据集除去首列的所有列名和tempdata进行cbind操作。

具体实现代码

1
2
3
4
5
6
7
8
9
> dft <- function(dataset) {
colnames <- names(dataset)[-1]
tempdata <- t(dataset)
rownames <- tempdata[1,]
tempdata <- as.data.table(tempdata[-1,], row.names = 1)
names(tempdata) <- rownames
tempdata <- cbind(tempdata, colnames)
tempdata
}

通过上述代码对tdata进行转置操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
> tdata1 <- dft(tdata)
> head(tdata1)
地区生产总值(亿元) 第一产业增加值(亿元) 第二产业增加值(亿元) 第三产业增加值(亿元) 农林牧渔业增加值(亿元) 工业增加值(亿元) 建筑业增加值(亿元)
1: 23014.59 140.21 4542.64 18331.74 142.60 3710.88 961.86
2: 21330.83 158.99 4544.80 16627.04 161.32 3746.77 902.66
3: 19800.81 159.64 4292.56 15348.61 161.83 3566.43 831.55
4: 17879.40 150.20 4059.27 13669.93 150.20 3294.32 764.95
5: 16251.93 136.27 3752.48 12363.18 136.27 3048.79 703.69
6: 14113.58 124.36 3388.38 10600.84 124.36 2763.99 624.39
批发和零售业增加值(亿元) 批发和零售贸易餐饮业增加值(亿元) 交通运输、仓储和邮政业增加值(亿元) 交通运输、仓储和邮电通信业增加值(亿元)
1: 2352.34 0.00 983.87 0.00
2: 2411.14 0.00 948.10 0.00
3: 2340.74 0.00 871.76 0.00
4: 2229.77 0.00 816.31 0.00
5: 2139.65 0.00 808.95 0.00
6: 1888.51 0.00 712.01 0.00
住宿和餐饮业增加值(亿元) 金融业增加值(亿元) 房地产业增加值(亿元) 其他行业增加值(亿元) 人均地区生产总值(元/人) colnames
1: 397.59 3926.28 1438.43 9100.73 106497.00 2015
2: 363.76 3357.71 1329.20 8110.18 99995.00 2014
3: 374.75 2943.13 1339.52 7371.10 94647.88 2013
4: 373.06 2536.91 1244.17 6469.71 87474.74 2012
5: 348.42 2215.41 1074.93 5775.82 81658.00 2011
6: 317.34 1863.61 1006.52 4812.85 73856.00 2010

大功告成,年份出现在最后一列。如果有强迫症,或者为了以后计算更加方便,还可以再加入一个参数,直接指定最后一列的列名,缺省值为"colnames"

1
2
3
4
5
6
7
8
9
10
> dft <- function(dataset, indexname = "colnames") {
colnames <- names(dataset)[-1]
tempdata <- t(dataset)
rownames <- tempdata[1,]
tempdata <- as.data.table(tempdata[-1,], row.names = 1)
names(tempdata) <- rownames
tempdata <- cbind(tempdata, colnames)
names(tempdata)[length(names(tempdata))] <- indexname
tempdata
}

然后就可以通过indexname参数来指定列名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 默认参数
> tdata1 <- dft(tdata)
> names(tdata1)
[1] "地区生产总值(亿元)" "第一产业增加值(亿元)" "第二产业增加值(亿元)"
[4] "第三产业增加值(亿元)" "农林牧渔业增加值(亿元)" "工业增加值(亿元)"
[7] "建筑业增加值(亿元)" "批发和零售业增加值(亿元)" "批发和零售贸易餐饮业增加值(亿元)"
[10] "交通运输、仓储和邮政业增加值(亿元)" "交通运输、仓储和邮电通信业增加值(亿元)" "住宿和餐饮业增加值(亿元)"
[13] "金融业增加值(亿元)" "房地产业增加值(亿元)" "其他行业增加值(亿元)"
[16] "人均地区生产总值(元/人)" "colnames"
# 指定参数
> tdata1 <- dft(tdata, "年份")
> names(tdata1)
[1] "地区生产总值(亿元)" "第一产业增加值(亿元)" "第二产业增加值(亿元)"
[4] "第三产业增加值(亿元)" "农林牧渔业增加值(亿元)" "工业增加值(亿元)"
[7] "建筑业增加值(亿元)" "批发和零售业增加值(亿元)" "批发和零售贸易餐饮业增加值(亿元)"
[10] "交通运输、仓储和邮政业增加值(亿元)" "交通运输、仓储和邮电通信业增加值(亿元)" "住宿和餐饮业增加值(亿元)"
[13] "金融业增加值(亿元)" "房地产业增加值(亿元)" "其他行业增加值(亿元)"
[16] "人均地区生产总值(元/人)" "年份"

通过以上函数,我们就可以快速转置数据框,进行数据操作了。

1
2
3
4
5
6
7
> tdata1[年份 == "2015年"]
地区生产总值(亿元) 第一产业增加值(亿元) 第二产业增加值(亿元) 第三产业增加值(亿元) 农林牧渔业增加值(亿元) 工业增加值(亿元) 建筑业增加值(亿元)
1: 23014.59 140.21 4542.64 18331.74 142.60 3710.88 961.86
批发和零售业增加值(亿元) 批发和零售贸易餐饮业增加值(亿元) 交通运输、仓储和邮政业增加值(亿元) 交通运输、仓储和邮电通信业增加值(亿元)
1: 2352.34 0.00 983.87 0.00
住宿和餐饮业增加值(亿元) 金融业增加值(亿元) 房地产业增加值(亿元) 其他行业增加值(亿元) 人均地区生产总值(元/人) 年份
1: 397.59 3926.28 1438.43 9100.73 106497.00 2015