【r<-分析】分析之前,准备数据

来源:《R核心技术手册》

数据分析项目中大多数的时间都用在了准备数据上,一个典型的项目80%的精力都花在分析而进行的发现、清洗和准备数据上。只有不到5%的精力用于分析(剩下的时间都耗在了写报告上面)。

合并数据集

数据分析中最常见的一个障碍是将存储在两个不同地方的数据组合到一起。

粘贴数据结构

R提供了几个函数可以将多个数据结构粘贴成一个数据结构。

paste

paste函数可以将多个字符型向量连接成一个向量,默认向量的值是用空格分隔的,我们可以通过sep参数指定分隔符号,而collapse参数可以用来指定这些值之间的连接符号。

x <- c("a", "b", "c", "d", "e")
y <- c("A", "B", "C", "E", "F")

# 默认
paste(x, y)
## [1] "a A" "b B" "c C" "d E" "e F"

# 使用自定义分隔符

paste(x, y, sep = ",")
## [1] "a,A" "b,B" "c,C" "d,E" "e,F"

# 指定连接符

paste(x, y, sep = "-", collapse = "#")
## [1] "a-A#b-B#c-C#d-E#e-F"

另外,使用简化版的paste0函数只提供连接参数,没有分隔。

paste0(x, y, collapse = "#")
## [1] "aA#bB#cC#dE#eF"

rbind 和 cbind

rbindcbind函数分别可以以增加行或列的形式将几个对象(矩阵或者数据框)合并起来。你可以将它想象为以垂直或者水平地将两张表拼在一起。

merge

merge(x, y, by = , by.x = , by.y = , ...)

xy指定用于合并的数据框,by对应xy共有的列名,后面by.xby.y用于分别指定用于合并的列名。

数据转换

数据框中常用的更改变量的函数是transform,它定义如下:

transform(`_data`, ...)

这个函数首先要指定一个数据框,跟着是一系列的表达式,表达式中的变量是数据框中的变量,transform函数会完成每个表达式中的计算,然后返回最终的数据框。

head(mtcars)
##                    mpg cyl disp  hp drat   wt qsec vs am gear carb
## Mazda RX4         21.0   6  160 110 3.90 2.62 16.5  0  1    4    4
## Mazda RX4 Wag     21.0   6  160 110 3.90 2.88 17.0  0  1    4    4
## Datsun 710        22.8   4  108  93 3.85 2.32 18.6  1  1    4    1
## Hornet 4 Drive    21.4   6  258 110 3.08 3.21 19.4  1  0    3    1
## Hornet Sportabout 18.7   8  360 175 3.15 3.44 17.0  0  0    3    2
## Valiant           18.1   6  225 105 2.76 3.46 20.2  1  0    3    1
mtcars.transformed <-  transform(mtcars, newVar = disp / hp)
mtcars.transformed
##                      mpg cyl  disp  hp drat   wt qsec vs am gear carb
## Mazda RX4           21.0   6 160.0 110 3.90 2.62 16.5  0  1    4    4
## Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.88 17.0  0  1    4    4
## Datsun 710          22.8   4 108.0  93 3.85 2.32 18.6  1  1    4    1
## Hornet 4 Drive      21.4   6 258.0 110 3.08 3.21 19.4  1  0    3    1
## Hornet Sportabout   18.7   8 360.0 175 3.15 3.44 17.0  0  0    3    2
## Valiant             18.1   6 225.0 105 2.76 3.46 20.2  1  0    3    1
## Duster 360          14.3   8 360.0 245 3.21 3.57 15.8  0  0    3    4
## Merc 240D           24.4   4 146.7  62 3.69 3.19 20.0  1  0    4    2
## Merc 230            22.8   4 140.8  95 3.92 3.15 22.9  1  0    4    2
## Merc 280            19.2   6 167.6 123 3.92 3.44 18.3  1  0    4    4
## Merc 280C           17.8   6 167.6 123 3.92 3.44 18.9  1  0    4    4
## Merc 450SE          16.4   8 275.8 180 3.07 4.07 17.4  0  0    3    3
## Merc 450SL          17.3   8 275.8 180 3.07 3.73 17.6  0  0    3    3
## Merc 450SLC         15.2   8 275.8 180 3.07 3.78 18.0  0  0    3    3
## Cadillac Fleetwood  10.4   8 472.0 205 2.93 5.25 18.0  0  0    3    4
## Lincoln Continental 10.4   8 460.0 215 3.00 5.42 17.8  0  0    3    4
##                     newVar
## Mazda RX4            1.455
## Mazda RX4 Wag        1.455
## Datsun 710           1.161
## Hornet 4 Drive       2.345
## Hornet Sportabout    2.057
## Valiant              2.143
## Duster 360           1.469
## Merc 240D            2.366
## Merc 230             1.482
## Merc 280             1.363
## Merc 280C            1.363
## Merc 450SE           1.532
## Merc 450SL           1.532
## Merc 450SLC          1.532
## Cadillac Fleetwood   2.302
## Lincoln Continental  2.140
## [到达getOption("max.print") -- 略过16行]]

对对象的每个元素进行函数运算

apply函数簇

该内容参考【r<-高级|理论】apply,lapply,sapply用法探索学习

plyr软件包

apply函数众多,参数也有些不同,幸运的是,我们可以使用plyr包来避免这些函数的细节。

plyr包包含了12个命名与其功能有逻辑关联的函数,用于将某个函数运行在某个R对象上,并且返回结果。每个函数的输入都是一个数组、数据框或者列表,输出也都是一个数组、数据框或者列表,或者什么都不输出。

输入 输出矩阵 输出数据框 输出列表 不输出
数组 aaply adply alply a_ply
数据框 daply ddply dlply d_ply
列表 laply ldply llply l_ply

所有的函数都接受下面的参数。

参数 描述 默认值
.data 输入的数据对象
.fun 要运行的函数 NULL
.progress 进度条类型(用create_progress构建);选项可包括“none”,“text”,“tk”和“win” “none”
.expand 若.data是一个数据框,则该参数控制输出如何扩展;.expand=TRUE表示1维输出,.expand=FALSE表示n维输出 TRUE
.parallel 指定是否并行地运行函数(通过foreach) FALSE
其他传递给.fun的参数

举几个例子:

library(plyr)
d <- data.frame(x=1:5, y=6:10)
# (1)输入为列表,输出也为列表
lapply(d, function(x) 2 ^ x)
## $x
## [1]  2  4  8 16 32
## 
## $y
## [1]   64  128  256  512 1024

# 等价命令是llply
llply(.data=d, .fun=function(x) 2^x)
## $x
## [1]  2  4  8 16 32
## 
## $y
## [1]   64  128  256  512 1024

# (2) 输入为矩阵,输出为列表
x = as.matrix(d)
apply(X = x, MARGIN = 1, FUN=paste, collapse=",")
## [1] "1,6"  "2,7"  "3,8"  "4,9"  "5,10"

# 等价命令
aaply(.data = x, .margins = 1, .fun=paste, collapse=",")
##      1      2      3      4      5 
##  "1,6"  "2,7"  "3,8"  "4,9" "5,10"

# (3)输入为数据框,输出为矩阵
t(sapply(d, FUN=function(x) 2 ^ x))
##   [,1] [,2] [,3] [,4] [,5]
## x    2    4    8   16   32
## y   64  128  256  512 1024
# 等价命令
aaply(.data=as.matrix(d), .margins = 2, .fun=function(x) 2 ^ x)
##    
## X1   1   2   3   4    5
##   x  2   4   8  16   32
##   y 64 128 256 512 1024

数据分段

shingle

Shingle对象是因子对象的连续性泛化,一个Shingle对象包括一个数字向量和一组间隔,各个间隔允许重叠,这种结构十分类似于屋檐上的瓦片结构。Shingle对象广泛应用于lattice包,它允许我们轻松地把条件或者分组变量作为连续变量使用。

lattice::shingle(x, intervals = unique(x))
## 
## Data:
##  [1]  1  2  3  4  5  6  7  8  9 10
## 
## Intervals:
##   min max count
## 1   1   6     6
## 2   2   7     6
## 3   3   8     6
## 4   4   9     6
## 5   5  10     6
## 
## Overlap between adjacent intervals:
## [1] 5 5 5 5

intervals参数用来指定在什么地方分割箱子,你可以用一个数值向量来指定分割的位置,也可以使用一个两列的矩阵,每一列表示一个特定的间距。equal.count函数可以用来创建一个shingle,每个箱子有相同个数的观测值:

lattice::equal.count(x)
## 
## Data:
##  [1]  1  2  3  4  5  6  7  8  9 10
## 
## Intervals:
##   min  max count
## 1 0.5  3.5     3
## 2 1.5  4.5     3
## 3 3.5  6.5     3
## 4 4.5  7.5     3
## 5 6.5  9.5     3
## 6 7.5 10.5     3
## 
## Overlap between adjacent intervals:
## [1] 2 1 2 1 2

Cut

cut函数可以很方便地将一个连续性变量切割成很多个小片段。输入是一个数值向量,输出是一个因子,因子的每个水平对应输入向量的每个区间范围。

cut(x, breaks, labels = NULL, include.lowest = FALSE, right=TRUE, dig.lab=3,
ordered_result = FALSE, ...)

例如,假设我们想要统计平均击球数据在某个范围内的选手的数量,可以使用cut函数与table函数:

# 读入示例数据
library(nutshell)
## 载入需要的程辑包:nutshell.bbdb
## 载入需要的程辑包:nutshell.audioscrobbler
data("batting.2008")
# 首先在数据框中加入击球平均值
batting.2008.AB <- transform(batting.2008, AVG = H / AB)

# 选择100 AB以上的球员(为了统计显著性)
batting.2008.over100AB <- subset(batting.2008.AB, subset = (AB > 100))

# 把结果分为10份
battingavg.2008.bins <- cut(batting.2008.over100AB$AVG, breaks = 10)

table(battingavg.2008.bins)
## battingavg.2008.bins
## (0.137,0.163] (0.163,0.189] (0.189,0.215]  (0.215,0.24]  (0.24,0.266] 
##             4             6            24            67           121 
## (0.266,0.292] (0.292,0.318] (0.318,0.344]  (0.344,0.37]  (0.37,0.396] 
##           132            70            11             5             2

利用分组变量合并对象

有时候,我们可能想要将几个相似的对象(向量或者数据框)合并成一个数据框,数据框中有一列用来表示数据的来源。lattice包中的make.groups函数可以实现这个功能:

library(lattice)
make.groups(...)

例如我们将下面不同的向量合成一个数据框:

hat.sizes <- seq(from = 6.25, to = 7.75, by = .25)
pants.sizes <- c(30:34, 36, 38, 40)
shoe.sizes <- seq(from=7, to=12)
lattice::make.groups(hat.sizes, pants.sizes, shoe.sizes)
##               data       which
## hat.sizes1    6.25   hat.sizes
## hat.sizes2    6.50   hat.sizes
## hat.sizes3    6.75   hat.sizes
## hat.sizes4    7.00   hat.sizes
## hat.sizes5    7.25   hat.sizes
## hat.sizes6    7.50   hat.sizes
## hat.sizes7    7.75   hat.sizes
## pants.sizes1 30.00 pants.sizes
## pants.sizes2 31.00 pants.sizes
## pants.sizes3 32.00 pants.sizes
## pants.sizes4 33.00 pants.sizes
## pants.sizes5 34.00 pants.sizes
## pants.sizes6 36.00 pants.sizes
## pants.sizes7 38.00 pants.sizes
## pants.sizes8 40.00 pants.sizes
## shoe.sizes1   7.00  shoe.sizes
## shoe.sizes2   8.00  shoe.sizes
## shoe.sizes3   9.00  shoe.sizes
## shoe.sizes4  10.00  shoe.sizes
## shoe.sizes5  11.00  shoe.sizes
## shoe.sizes6  12.00  shoe.sizes

随机抽样

有时候数据太多,或者出于统计或计算性能的原因,你想要将数据随机分为几部分构建模型(通常分为训练集、测试集和评估集)。

最简单地方法就是使用sample函数,它可以对一个向量做随机抽样。

sample(x, size, replace = FALSE, prob = NULL)

当对数据框做sample操作时,实际返回的是列的随机抽样结果,而不是行。因为数据框是向量的列表,sample实际抽样的是这个列表的元素。所以要注意一下。

对于观察结果做行的随机抽样,需要使用sample函数创建一组行号的抽样结果,然后再使用索引选取这些行号所对应的行。比如我们随机抽样batting.2008数据集的5条记录:

batting.2008[sample(1:nrow(batting.2008), 5), ]
##       nameLast nameFirst weight height bats throws      debut birthYear
## 478  Rodriguez Francisco    175     72    R      R 2002-09-18      1982
## 350     Seanez      Rudy    185     70    R      R 1989-09-07      1968
## 1019 Francisco       Ben    190     73    R      R 2007-05-01      1981
## 1011    Musser      Neal    235     73    L      L 2007-04-21      1980
## 327      Riske     David    180     74    R      R 1999-08-14      1976
##       playerID yearID stint teamID lgID   G G_batting  AB  R   H 2B 3B HR
## 478  rodrifr03   2008     1    LAA   AL  76         4   0  0   0  0  0  0
## 350  seaneru01   2008     1    PHI   NL  42        41   0  0   0  0  0  0
## 1019 francbe01   2008     1    CLE   AL 121       121 447 65 119 32  0 15
## 1011 mussene01   2008     1    KCA   AL   1         0   0  0   0  0  0  0
## 327  riskeda01   2008     1    MIL   NL  45        44   1  0   0  0  0  0
##      RBI SB CS BB SO IBB HBP SH SF GIDP G_old
## 478    0  0  0  0  0   0   0  0  0    0     4
## 350    0  0  0  0  0   0   0  0  0    0    41
## 1019  54  4  3 40 86   0   6  2  4   10   121
## 1011   0  0  0  0  0   0   0  0  0    0     1
## 327    0  0  0  0  0   0   0  0  0    0    44

还可以使用这种技术做更复杂的随机抽样,比如你想要随机统计3个对的情况,可以这样:

batting.2008$teamID <- as.factor(batting.2008$teamID)
levels(batting.2008$teamID)
##  [1] "ARI" "ATL" "BAL" "BOS" "CHA" "CHN" "CIN" "CLE" "COL" "DET" "FLO"
## [12] "HOU" "KCA" "LAA" "LAN" "MIL" "MIN" "NYA" "NYN" "OAK" "PHI" "PIT"
## [23] "SDN" "SEA" "SFN" "SLN" "TBA" "TEX" "TOR" "WAS"

# 抽样例子
sample(levels(batting.2008$teamID), 3)
## [1] "BAL" "SLN" "SEA"
# 使用例子
batting.2008.3teams <- batting.2008[is.element(batting.2008$teamID, sample(levels(batting.2008$teamID),3)), ]
batting.2008.3teams
##         nameLast nameFirst weight height bats throws      debut birthYear
## 6         Ardoin     Danny    218     72    R      R 2000-08-02      1974
## 9        Aurilia      Rich    170     72    R      R 1995-09-06      1971
## 19        Beimel       Joe    201     74    L      L 2001-04-08      1977
## 24       Bennett      Gary    190     72    R      R 1995-09-24      1972
## 27        Berroa     Angel    175     71    R      R 2001-09-18      1978
## 30         Blake     Casey    200     74    R      R 1999-08-14      1973
##       playerID yearID stint teamID lgID   G G_batting  AB   R   H 2B 3B HR
## 6    ardoida01   2008     1    LAN   NL  24        24  51   3  12  1  0  1
## 9    aurilri01   2008     1    SFN   NL 140       140 407  33 115 21  1 10
## 19   beimejo01   2008     1    LAN   NL  71        69   0   0   0  0  0  0
## 24   bennega01   2008     1    LAN   NL  10        10  21   1   4  1  0  1
## 27   berroan01   2008     1    LAN   NL  84        84 226  26  52 13  1  1
## 30   blakeca01   2008     2    LAN   NL  58        58 211  25  53 12  1 10
##      RBI SB CS BB  SO IBB HBP SH SF GIDP G_old
## 6      4  1  0  2  10   0   1  0  0    2    24
## 9     52  1  1 30  56   4   1  0  2   11   140
## 19     0  0  0  0   0   0   0  0  0    0    69
## 24     4  0  0  2   0   0   0  0  0    1    10
## 27    16  0  0 20  41   4   4  6  0   13    84
## 30    23  1  0 16  52   5   4  0  2    9    58
## [到达getOption("max.print") -- 略过134行]]

这个函数对于数据的各种复杂抽样非常方便,但你可能还需要用到更复杂的抽样方式,比如分层抽样、整群抽样、最大熵抽样,这些方法都可以在sampling包中找到。

汇总函数

tapply与aggregate

tapply函数用于向量的汇总分析,是一个非常灵活的函数。可以设置对向量X的某个子集做汇总,也可以指定汇总函数:

tapply(X, INDEX, FUN = , ..., simplify = )

比如计算各队本垒打的总数:

tapply(X=batting.2008$HR, INDEX=list(batting.2008$teamID), FUN=sum)
## ARI ATL BAL BOS CHA CHN CIN CLE COL DET FLO HOU KCA LAA LAN MIL MIN NYA 
## 159 130 172 173 235 184 187 171 160 200 208 167 120 159 137 198 111 180 
## NYN OAK PHI PIT SDN SEA SFN SLN TBA TEX TOR WAS 
## 172 125 214 153 154 124  94 174 180 194 126 117

也可以使用返回多个值的函数,例如fivenum计算各个联盟球员击球平均数:

tapply(batting.2008$H/batting.2008$AB, INDEX=list(batting.2008$lgID), fivenum)
## $AL
## [1] 0.000 0.176 0.249 0.283 1.000
## 
## $NL
## [1] 0.0000 0.0952 0.2173 0.2680 1.0000

plyr包中没有tapply的等价功能。

by是和tapply有密切关系的一个函数,区别在于by是用于数据框的。下面是一个例子:

by(batting.2008[, c("H", "2B", "3B", "HR")],
   INDICES = list(batting.2008$lgID, batting.2008$bats), FUN=mean)
## Warning in mean.default(data[x, , drop = FALSE], ...): 参数不是数值也不是逻
## 辑值:回覆NA

## Warning in mean.default(data[x, , drop = FALSE], ...): 参数不是数值也不是逻
## 辑值:回覆NA

## Warning in mean.default(data[x, , drop = FALSE], ...): 参数不是数值也不是逻
## 辑值:回覆NA

## Warning in mean.default(data[x, , drop = FALSE], ...): 参数不是数值也不是逻
## 辑值:回覆NA

## Warning in mean.default(data[x, , drop = FALSE], ...): 参数不是数值也不是逻
## 辑值:回覆NA

## Warning in mean.default(data[x, , drop = FALSE], ...): 参数不是数值也不是逻
## 辑值:回覆NA
## : AL
## : B
## [1] NA
## -------------------------------------------------------- 
## : NL
## : B
## [1] NA
## -------------------------------------------------------- 
## : AL
## : L
## [1] NA
## -------------------------------------------------------- 
## : NL
## : L
## [1] NA
## -------------------------------------------------------- 
## : AL
## : R
## [1] NA
## -------------------------------------------------------- 
## : NL
## : R
## [1] NA

另一个用于数据汇总的函数是aggregate

aggregate(x, by, FUN, ...)

也可以用于时间序列,参数略有不同。

下面看一个按球队统计击球数的例子:

aggregate(x=batting.2008[, c("AB", "H", "BB", "2B", "3B", "HR")],
          by=list(batting.2008$teamID), FUN=sum)
##    Group.1   AB    H  BB  2B 3B  HR
## 1      ARI 5409 1355 587 318 47 159
## 2      ATL 5604 1514 618 316 33 130
## 3      BAL 5559 1486 533 322 30 172
## 4      BOS 5596 1565 646 353 33 173
## 5      CHA 5553 1458 540 296 13 235
## 6      CHN 5588 1552 636 329 21 184
## 7      CIN 5465 1351 560 269 24 187
## 8      CLE 5543 1455 560 339 22 171
## 9      COL 5557 1462 570 310 28 160
## 10     DET 5641 1529 572 293 41 200
## 11     FLO 5499 1397 543 302 28 208
## 12     HOU 5451 1432 449 284 22 167
## 13     KCA 5608 1507 392 303 28 120
## 14     LAA 5540 1486 481 274 25 159
## 15     LAN 5506 1455 543 271 29 137
## 16     MIL 5535 1398 550 324 35 198
## 17     MIN 5641 1572 529 298 49 111
## 18     NYA 5572 1512 535 289 20 180
## 19     NYN 5606 1491 619 274 38 172
## 20     OAK 5451 1318 574 270 23 125
## 21     PHI 5509 1407 586 291 36 214
## 22     PIT 5628 1454 474 314 21 153
## 23     SDN 5568 1390 518 264 27 154
## 24     SEA 5643 1498 417 285 20 124
## 25     SFN 5543 1452 452 311 37  94
## 26     SLN 5636 1585 577 283 26 174
## 27     TBA 5541 1443 626 284 37 180
## 28     TEX 5728 1619 595 376 35 194
## [到达getOption("max.print") -- 略过2行]]

计数

使用tabulatetable函数。


reshape包另起一文单独写下,不要将内置的reshape函数与reshape包混淆。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容

  • 2017年夏天开始学习R语言。 第1章 R语言介绍 1.1 R的获取和安装 下载Rgui:http://cran....
    弹跳骑士阅读 7,740评论 0 10
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,034评论 1 32
  • 虚拟机分两部分:管理资源,执行指令。 执行指令部分:协程,所有协程共享一个虚拟机。也可以理解成线程,但是同时只有一...
    小小青蛙不怕风吹雨打阅读 372评论 0 0
  • 夜晚 找不到灵魂的寄托 地面的风怒吼着 肆虐生命的预约 三月的北方 着实有点阵阵忧伤 但,请不要绝望 随后春意便漫...
    君凉阅读 197评论 5 12
  • 壹 张三丰自创“倚天屠龙功”,通过屠龙刀倚天剑的24字口诀将书法与武功无缝融合。修为到了仙境,举手投足都是神功。 ...
    书生慧慧子阅读 892评论 0 2