R语言实战—3

基本数据管理

4-2 创建新变量
#方法1
mydata<-data.frame(x1 = c(2, 2, 6, 4),x2 = c(3, 4, 2, 8))
mydata$sumx <- mydata$x1 + mydata$x2
mydata$meanx <- (mydata$x1 + mydata$x2)/2

#方法2
attach(mydata)
mydata$sumx <- x1 + x2
mydata$meanx <- (x1 + x2)/2
detach(mydata)

#方法3
mydata <- transform(mydata,sumx = x1 + x2,meanx = (x1 + x2)/2)

fix(leadership)来调用一个交互式的编辑器。然后单击变量名,然后在弹出的对话框中将其重命名

或通过names()函数来重命名变量。例如:names(leadership)[2] <- "testDate" #2指第二个变量
names(leadership)[6:10] <- c("item1", "item2", "item3", "item4", "item5")

plyr包中有一个rename()函数,可用于修改变量名。
rename(dataframe, c(oldname="newname",oldname="newname",...))

重编码缺失值
leadership$age[leadership$age == 99] <- NA

多数的数值函数都拥有一个na.rm=TRUE选项,可以在计算之前移除缺失值并使用剩余值进行计算:
x <- c(1, 2, NA, 3)
y <- sum(x, na.rm=TRUE)

函数na.omit()移除所有含有缺失数据的行。

4-4 使用na.omit()删除不完整的观测
> leadership
 manager     date country gender age q1 q2 q3 q4 q5
1      1 10/24/08      US      M  32  5  4  5  5  5
2      2 10/28/08      US      F  40  3  5  2  5  5
3      3 10/01/08      UK      F  25  3  5  5  5  2
4      4 10/12/08      UK      M  39  3  3  4  NA NA
5      5 05/01/09      UK      F  NA  2  2  1  2  1
> newdata <- na.omit(leadership)
> newdata
 manager     date country gender age q1 q2 q3 q4 q5
1      1 10/24/08      US      M  32  5  4  5  5  5
2      2 10/28/08      US      F  40  3  5  2  5  5
3      3 10/01/08      UK      F  25  3  5  5  5  2
4-5 转换数据类型
> a <- c(1,2,3)
> a
[1] 1 2 3
> is.numeric(a)
[1] TRUE
> is.vector(a)
[1] TRUE
> a <- as.character(a)
> a
[1] "1" "2" "3"
> is.numeric(a)
[1] FALSE
> is.vector(a)
[1] TRUE
> is.character(a)
[1] TRUE

使用order()函数对一个数据框进行排序。默认的排序顺序是升序。在排序变量的前边加一个减号即可得到降序的排序结果。
newdata <- leadership[order(leadership$age),]
newdata <- leadership[order(gender, age),] #同样性别中按年龄升序排序

要横向合并两个数据框(数据集),请使用merge()函数。在多数情况下,两个数据框是通过一个或多个共有变量进行联结的(即一种内联结,inner join)。例如:
total <- merge(dataframeA, dataframeB, by="ID")
将dataframeA和dataframeB按照ID进行了合并。类似地,
total <- merge(dataframeA, dataframeB, by=c("ID","Country"))
将两个数据框按照ID和Country进行了合并。类似的横向联结通常用于向数据框中添加变量。

如果要直接横向合并两个矩阵或数据框,并且不需要指定一个公共索引,那么可以直接使用cbind()函数:
total <- cbind(A, B)
这个函数将横向合并对象A和对象B。为了让它正常工作,每个对象必须拥有相同的行数,以同顺序排序。

纵向合并两个数据框(数据集),请使用rbind()函数:
total <- rbind(dataframeA, dataframeB)
两个数据框必须拥有相同的变量,不过它们的顺序不必一定相同。如果dataframeA中拥有dataframeB中没有的变量,请在合并它们之前做以下某种处理:
 删除dataframeA中的多余变量;
 在dataframeB中创建追加的变量并将其值设为NA(缺失)。

从一个大数据集中选择有限数量的变量来创建一个新的数据集
newdata <- leadership[, c(6:10)]    #将行下标留空(,)表示默认选择所有行
或者
myvars <- c("q1", "q2", "q3", "q4", "q5")
newdata <-leadership[myvars]
或者
myvars <- paste("q", 1:5, sep=" ")
newdata <- leadership[myvars]
剔除变量q3和q4
方法一:
myvars <- names(leadership) %in% c("q3", "q4")
newdata <- leadership[!myvars]
方法二(在知道q3和q4是第8个和第9个变量的情况下):
newdata <- leadership[c(-8,-9)]
方法三:
leadership$q3 <- leadership$q4 <- NULL
选入观测
方法一:
newdata <- leadership[1:3,]
newdata <- leadership[leadership$gender=="M" &leadership$age > 30,]

方法二:subset()函数
newdata <- subset(leadership, age >= 35 | age < 24,
select=c(q1, q2, q3, q4))
newdata <- subset(leadership, gender=="M" & age > 25,
select=gender:q4)



默认情况下,函数scale()对矩阵或数据框的指定列进行均值为0、标准差为1的标准化:
newdata <- scale(mydata)
要对每一列进行任意均值和标准差的标准化:
newdata <- scale(mydata)SD + M
其中的M是想要的均值,SD为想要的标准差。
要对指定列而不是整个矩阵或数据框进行标准化:
newdata <- transform(mydata, myvar = scale(myvar)
10+50)
此句将变量myvar标准化为均值50、标准差为10的变量。

5-4 将函数应用于数据对象
> a <- 5
> sqrt(a)
[1] 2.236068
> b <- c(1.243, 5.654, 2.99)
> round(b)
[1] 1 6 3
> c <- matrix(runif(12), nrow=3)
> c
[,1] [,2] [,3] [,4]
[1,] 0.4205 0.355 0.699 0.323
[2,] 0.0270 0.601 0.181 0.926
[3,] 0.6682 0.319 0.599 0.215
> log(c)
[,1] [,2] [,3] [,4]
[1,] -0.866 -1.036 -0.358 -1.130
[2,] -3.614 -0.508 -1.711 -0.077
[3,] -0.403 -1.144 -0.513 -1.538
> mean(c)
[1] 0.444
函数mean()求得的是矩阵中全部12个元素的均值。但如果希望求的是各行的均值或各列的均值呢?
R中提供了一个apply()函数,可将一个任意函数“应用”到矩阵、数组、数据框的任何维度上。
apply(x, MARGIN, FUN, ...)
其中,x为数据对象,MARGIN是维度的下标,FUN是由你指定的函数,而...则包括了任何想传递给FUN的参数。
在矩阵或数据框中,MARGIN=1表示行,MARGIN=2表示列。
5-5 将一个函数应用到矩阵的所有行(列)
> mydata <- matrix(rnorm(30), nrow=6)
> mydata
[,1] [,2] [,3] [,4] [,5]
[1,] 0.71298 1.368 -0.8320 -1.234 -0.790
[2,] -0.15096 -1.149 -1.0001 -0.725 0.506
[3,] -1.77770 0.519 -0.6675 0.721 -1.350
[4,] -0.00132 -0.308 0.9117 -1.391 1.558
[5,] -0.00543 0.378 -0.0906 -1.485 -0.350
[6,] -0.52178 -0.539 -1.7347 2.050 1.569
> apply(mydata, 1, mean)
[1] -0.155 -0.504 -0.511 0.154 -0.310 0.165
> apply(mydata, 2, mean)
[1] -0.2907 0.0449 -0.5688 -0.3442 0.1906
将学生的各科考试成绩组合为单一的成绩衡量指标,基于相对名次(前20%、下20%、等等)给出从A到F的评分,
根据学生姓氏和名字的首字母对花名册进行排序。
5-6 方案一
> options(digits=2)     #限定了输出小数点后数字的位数
> Student <- c("John Davis", "Angela Williams", "Bullwinkle Moose","David Jones", 
"Janice Markhammer", "Cheryl Cushing","Reuven Ytzrhak", "Greg Knox",
 "Joel England","Mary Rayburn")
> Math <- c(502, 600, 412, 358, 495, 512, 410, 625, 573, 522)
> Science <- c(95, 99, 80, 82, 75, 85, 80, 95, 89, 86)
> English <- c(25, 22, 18, 15, 20, 28, 15, 30, 27, 18)
> roster <- data.frame(Student, Math, Science, English,
stringsAsFactors=FALSE)
> z <- scale(roster[,2:4])       
#由于数学、科学和英语考试的分值不同(均值和标准差相去甚远),在组合之前需要先让它们变得可以比较。
#一种方法是将变量进行标准化,这样每科考试的成绩就都是用单位标准差来表示,而不是以原始的尺度来表示了。
> score <- apply(z, 1, mean)
> roster <- cbind(roster, score)
> y <- quantile(score, c(.8,.6,.4,.2))
#quantile()给出了学生综合得分的百分位数。可以看到,成绩为A的分界点为0.74,B的分界点为0.44
> roster$grade[score >= y[1]] <- "A"
> roster$grade[score < y[1] & score >= y[2]] <- "B"
> roster$grade[score < y[2] & score >= y[3]] <- "C"
> roster$grade[score < y[3] & score >= y[4]] <- "D"
> roster$grade[score < y[4]] <- "F"
> name <- strsplit((roster$Student), " ")
#使用函数strsplit()以空格为界把学生姓名拆分为姓氏和名字。
> Lastname <- sapply(name, "[", 2)
> Firstname <- sapply(name, "[", 1)
> roster <- cbind(Firstname,Lastname, roster[,-1])
> roster <- roster[order(Lastname,Firstname),]
#使用函数sapply()提取列表中每个成分的第一个元素,放入一个储存名字的向量Firstname,
#并提取每个成分的第二个元素,放入一个储存姓氏的向量Lastname。
#"["是一个可以提取某个对象的一部分的函数
#使用cbind()合并列表
#由于已经不再需要student变量,在下标中使用–1将其丢弃。
> roster
Firstname Lastname Math Science English score grade
6 Cheryl Cushing 512 85 28 0.35 C
1 John Davis 502 95 25 0.56 B
9 Joel England 573 89 27 0.70 B
4 David Jones 358 82 15 -1.16 F
8 Greg Knox 625 95 30 1.34 A
5 Janice Markhammer 495 75 20 -0.63 D
3 Bullwinkle Moose 412 80 18 -0.86 D
10 Mary Rayburn 522 86 18 -0.18 C
2 Angela Williams 600 99 22 0.92 A
7 Reuven Ytzrhak 410 80 15 -1.05 F

1. for结构
for循环重复地执行一个语句,直到某个变量的值不再包含在序列seq中为止。
for (var in seq) statement
eg.
for (i in 1:10) print("Hello") #单词Hello被输出了10次
2. while结构
while循环重复地执行一个语句,直到条件不为真为止。
while (cond) statement
eg.
i <- 10
while (i > 0) {print("Hello"); i <- i - 1}

1. if-else结构
控制结构if-else在某个给定条件为真时执行语句。也可以同时在条件为假时执行另外的语句。
if (cond) statement
if (cond) statement1 else statement2
示例如下:
if (is.character(grade)) grade <- as.factor(grade)
if (!is.factor(grade)) grade <- as.factor(grade) else print("Grade already is a factor")
在第一个实例中,如果grade是一个字符向量,它就会被转换为一个因子。在第二个实例中,两个语句择其一执行。如果grade不是一个因子(注意符号!),它就会被转换为一个因子。如果它是一个因子,就会输出一段信息。
2. ifelse结构
ifelse结构是if-else结构比较紧凑的向量化版本,
ifelse(cond, statement1, statement2)
若cond为TRUE,则执行第一个语句;若cond为FALSE,则执行第二个语句。示例如下:
ifelse(score > 0.5, print("Passed"), print("Failed"))
outcome <- ifelse (score > 0.5, "Passed", "Failed")
在程序的行为是二元时,或者希望结构的输入和输出均为向量时,请使用ifelse。
3. switch结构
switch根据一个表达式的值选择语句执行。
switch(expr, ...)
其中的...表示与expr的各种可能输出值绑定的语句。

5-7 一个switch示例
> feelings <- c("sad", "afraid")
> for (i in feelings)
      print(
         switch(i,
             happy = "I am glad you are happy",
             afraid = "There is nothing to fear",
             sad = "Cheer up",
             angry = "Calm down now"
         )
      )
[1] "Cheer up"
[1] "There is nothing to fear"
5-9 数据集的转置
> cars <- mtcars[1:5,1:4]
> cars
mpg cyl disp hp
Mazda RX4 21.0 6 160 110
Mazda RX4 Wag 21.0 6 160 110
Datsun 710 22.8 4 108 93
Hornet 4 Drive 21.4 6 258 110
Hornet Sportabout 18.7 8 360 175
> t(cars)           #行名将成为变量(列)名
     Mazda RX4 Mazda RX4 Wag Datsun 710 Hornet 4 Drive Hornet Sportabout
mpg         21            21       22.8           21.4             18.7
cyl          6             6        4.0            6.0              8.0
disp       160           160      108.0          258.0            360.0
hp         110           110       93.0          110.0            175.0

整合数据


1.融合
library(reshape2)
md <- melt(mydata, id=c("ID", "Time"))

2. 重铸
newdata <- dcast(md, formula, fun.aggregate)
md为已融合的数据,formula描述了想要的最后结果,而fun.aggregate是(可选的)数据整合函数。其接受的公式形如:rowvar1 + rowvar2 + ... ~ colvar1 + colvar2 + ...
在这一公式中,rowvar1 + rowvar2 + ...定义了要划掉的变量集合,以确定各行的内容,
而colvar1 + colvar2 + ...则定义了要划掉的、确定各列内容的变量集合。

你可能感兴趣的:(R语言实战—3)