Advanced R之构造子集
转发请声明出处:http://www.cnblogs.com/lizichao/p/4794733.html
构造子集
R构造子集的操作功能强大而且速度快。精通构造子集者可以用简洁的方式表达复杂的操作,很少有其他语言能做到这一点。构造子集学习起来比较困难,因为需要掌握一系列相互关联的概念:
- 3种构造子集操作符。
- 6类子集。
- 不同对象(比如向量、列表、因子、矩阵、数据框)行为上的重要不同。
- 联合使用构造子集与赋值。
本章将帮助掌握构造子集,让我们从最简单的构造子集开始:用[构造原子向量的子集。然后逐渐扩展你的知识,首先学习更加复杂的数据类型(比如数组和列表),然后是其他构造子集操作符,[[和$。接着你将学习如何组合使用构造子集和赋值来修改对象的一部分,最后,你将看到很多有用的应用。
构造子集与str()相辅相成。str()展示任意对象的结构,构造子集让你选取你所感兴趣的部分。
测试
做下下面的测试,以确定你是否需要阅读本章。如果可以很快想到答案,你可以跳过本章。可以在answers中检查你的答案是否正确。
- 构造向量的子集时,使用正整数、负整数、一个逻辑向量或者一个字符向量,结果会如何?
- 当作用于列表时,[,[[,$有何不同?
- 什么时候使用
drop = FALSE
? - 如果x是一个矩阵,那么
x[] <- 0
会发生什么?这与x <- 0
有何不同? - 如何使用命名向量来重新标记分类变量?
概述
- 数据类型部分以学习[开始。首先学习可以用来构造原子向量子集的6种数据类型,然后学习这6种数据类型如何构造列表、矩阵、数据框和S3对象的子集。
- 构造子集操作符部分扩展关于构造子集操作符的知识,包括[[和$,关注点在于结构简化与保留的重要规律。
- 构造子集与赋值部分你将学习局部赋值的技巧,即联合使用构造子集和赋值来改变对象的一部分。
- 应用部分介绍8种重要但是不明显的构造子集应用,这些应用在数据分析中经常用到。
数据类型
构造原子向量子集是最简单的,然后归纳到高维和其他更加复杂的对象。我们从[开始,[是最常见的构造子集操作符。构造子集操作符部分将介绍[[和$,它们是另外2种主要的构造子集操作符。
原子向量
让我们看下对于一个简单的向量x,用不同数据类型来构造其子集会有何不同。
x <- c(2.1, 4.2, 3.3, 5.4)
注意,向量中每个元素小数点后的数字,表明该元素在向量中的位置。
可以用5样东西来构造向量的子集:
正整数,这时将得到对应位置的元素:
x[c(, )]
#> [] 3.3 2.1
x[order(x)]
#> [] 2.1 3.3 4.2 5.4 # Duplicated indices yield duplicated values
x[c(, )]
#> [] 2.1 2.1 # Real numbers are silently truncated to integers
x[c(2.1, 2.9)]
#> [] 4.2 4.2负整数,这时会忽略对应位置的元素:
x[-c(, )]
#> [] 4.2 5.4
不能混合使用正整数和负整数:
x[c(-, )]
#> Error in x[c(-, )]: only 's may be mixed with negative subscripts
逻辑向量,这时会选择对应的逻辑值为真的元素。这可能是最有用的构造子集方式,因为你可以利用创建逻辑向量的表达式:
x[c(TRUE, TRUE, FALSE, FALSE)]
#> [] 2.1 4.2
x[x > ]
#> [] 4.2 3.3 5.4如果逻辑向量的长度,比子集所在向量的长度短,逻辑向量将被循环复制直到达到相同的长度。
x[c(TRUE, FALSE)]
#> [] 2.1 3.3
# Equivalent to
x[c(TRUE, FALSE, TRUE, FALSE)]
#> [] 2.1 3.3缺失值所在的下标,一般对应的也会得到一个缺失值:
x[c(TRUE, TRUE, NA, FALSE)]
#> [] 2.1 4.2 NA空,此时返回原向量。这对于向量来说没有用,但是对于矩阵、数据框和数组非常有用。当联合使用构造子集与赋值时也比较有用。
x[]
#> [] 2.1 4.2 3.3 5.40,此时返回一个长度为0的向量。这通常不是你的意图,但是对于产生测试数据是有用的。
x[]
#> numeric()如果向量是命了名的,你也可以使用:
字符向量,此时返回匹配的元素。
(y <- setNames(x, letters[:]))
#> a b c d
#> 2.1 4.2 3.3 5.4
y[c("d", "c", "a")]
#> d c a
#> 5.4 3.3 2.1 # Like integer indices, you can repeat indices
y[c("a", "a", "a")]
#> a a a
#> 2.1 2.1 2.1 # When subsetting with [ names are always matched exactly
z <- c(abc = , def = )
z[c("a", "d")]
#> <NA> <NA>
#> NA NA
列表
构造列表的子集与构造原子向量子集的方式相同。对列表使用[构造子集总是得到一个列表;[[和$得到列表的内容,如下所述。
矩阵和数组
对于高维数据结构,有3种方式构造子集:
- 使用多个向量。
- 使用单个向量。
- 使用矩阵。
构造矩阵(2维)和数组(>2维)子集最常见的方式,是对1维情况下构造子集的简单拓展:对于每个维度提供一个1维的下标,用逗号分隔。用空格构造子集此时比较有用,因为它允许你保留所有的行或者列。
a <- matrix(:, nrow = )
colnames(a) <- c("A", "B", "C")
a[:, ]
#> A B C
#> [,]
#> [,]
a[c(T, F, T), c("B", "A")]
#> B A
#> [,]
#> [,]
a[, -]
#> A C
默认情况下,[会简化结果,即将结果的维度降到可能的最低维度。参见结构简化与保留部分介绍的如何避免这种情况。
因为矩阵和数组是通过向量实现的,即具有特殊属性的向量,所以可以用一个向量来对它们构造子集。这种情况下,矩阵和数组会表现的像向量。R中的数组以列为首要存储顺序。
(vals <- outer(:, :, FUN = "paste", sep = ","))
#> [,] [,] [,] [,] [,]
#> [,] "1,1" "1,2" "1,3" "1,4" "1,5"
#> [,] "2,1" "2,2" "2,3" "2,4" "2,5"
#> [,] "3,1" "3,2" "3,3" "3,4" "3,5"
#> [,] "4,1" "4,2" "4,3" "4,4" "4,5"
#> [,] "5,1" "5,2" "5,3" "5,4" "5,5"
vals[c(, )]
#> [] "4,1" "5,3"
也可以利用整形矩阵来对更高维度的数据结构构造子集(或者,如果是命名的数据结构,可以用字符矩阵)。对于子集所在的数组,矩阵的每一行确定了值的位置,每一列对应一个维度。也就是说,用2列的矩阵来构造矩阵的子集,用3列的矩阵构造3维数组的矩阵。得到的结果是向量:
vals <- outer(:, :, FUN = "paste", sep = ",")
select <- matrix(ncol = , byrow = TRUE, c(
, ,
, ,
,
))
vals[select]
#> [] "1,1" "3,1" "2,4"
数据框
数据框具有列表和矩阵的特征:如果用一个向量对数据框构造子集,数据框表现的像列表;如果使用2个向量,它表现的像矩阵。
df <- data.frame(x = :, y = :, z = letters[:]) df[df$x == , ]
#> x y z
#> b
df[c(, ), ]
#> x y z
#> a
#> c # There are two ways to select columns from a data frame
# Like a list:
df[c("x", "z")]
#> x z
#> a
#> b
#> c
# Like a matrix
df[, c("x", "z")]
#> x z
#> a
#> b
#> c # There's an important difference if you select a single
# column: matrix subsetting simplifies by default, list
# subsetting does not.
str(df["x"])
#> 'data.frame': obs. of variable:
#> $ x: int
str(df[, "x"])
#> int [:]
S3对象
S3对象由原子向量、数组、列表组成,所以你可以使用上述方法以及str()得到的信息,来构造S3对象的子集。
S4对象
对于S4对象,还有另外2种构造子集的运算符:@(等同于$),slot()(等同于[[)。@比$有更加严格的限制,即如果槽不存在会返回错误。这些内容在the OO field guide介绍。
练习
下列代码试图构造数据框子集,请修复其中的错误:
mtcars[mtcars$cyl = , ]
mtcars[-:, ]
mtcars[mtcars$cyl <= ]
mtcars[mtcars$cyl == | , ]对于
x <- 1:5;为何
x[NA]
得到5个缺失值?(思路:这与x[NA_real_]
为何不同?)upper.tri()
返回什么?为何可以使用它对矩阵构造子集?对于这种情况,我们是否需要额外的构造子集规则来描述它?x <- outer(:, :, FUN = "*")
x[upper.tri(x)]为何
mtcars[1:20]
返回错误?它与mtcars[1:20, ]
为何不同?自己动手写一个函数,取矩阵对角线上的元素(该函数应该类似于
diag(x)
,其中x是矩阵)。df[is.na(df)] <- 0
什么意思?为何可以这样使用?
构造子集操作符
另外2种构造子集操作符是[[和$。[[类似于[,只不过[[只返回一个单独的值,而且允许构造列表的子集。$是[[的简化,它利用字符构造子集,很有用。
当构造列表子集时需要使用[[。因为[应用到列表时总是得到一个列表:而不是列表的内容。为了得到列表内容,需要使用[[:
“如果x是拉货的火车,x[[5]]是5号车厢中的货物;x[4:6]是4到6号车厢。”
— @RLangTip
因为[[只返回一个值,必须使用正整数或者字符串来使用[[:
a <- list(a = , b = )
a[[]]
#> []
a[["a"]]
#> [] # If you do supply a vector it indexes recursively
b <- list(a = list(b = list(c = list(d = ))))
b[[c("a", "b", "c", "d")]]
#> []
# Same as
b[["a"]][["b"]][["c"]][["d"]]
#> []
因为数据框是列组成的列表,所以要使用[[来提取数据框的一列:mtcars[[1]]
,mtcars[["cyl"]]
。
S3对象和S4对象可以覆盖[和[[操作符的标准行为,所以对于不同的对象会有不同的表现。关键的不同点往往在于如何选择结构简化或者保留,以及默认情况。
结构简化和保留
理解子集结构简化和保留的区别非常重要。结构简化是指返回的子集的数据结构尽可能简单,只要能表示输出即可,对于交互来说这很有用因为这样往往可以得到想要的结果。结构保留是指输入与输出的结构相同,在编程中这往往更好些,因为结果一直是同类型的。构造矩阵和数据框子集时,忽略drop = FALSE是个最常见的编程错误。(在测试时可以正常工作,但是对于只有一列的数据框,会以不可预测且不清楚的方式失败。)
不幸的是,对不同数据类型,如何在简化与保留之间切换那,这里总结了下表。
简化 | 保留 | |
向量 | x[[1]] |
x[1] |
列表 | x[[1]] |
x[1] |
因子 | x[1:4, drop = T] |
x[1:4] |
数组 | x[1, ] or x[, 1] |
x[1, , drop = F] or x[, 1, drop = F] |
数据框 | x[, 1] or x[[1]] |
x[, 1, drop = F] or x[1] |
结构保留对于所有的数据类型都相同:输出与输入类型相同。不同数据类型的结构简化行为略有不同,如下:
原子向量:移除名称。
x <- c(a = , b = )
x[]
#> a
#>
x[[]]
#> []列表:返回列表中的对象,而不是单个元素的列表。
y <- list(a = , b = )
str(y[])
#> List of
#> $ a: num
str(y[[]])
#> num因子:丢掉所有没有用到的因子水平。
z <- factor(c("a", "b"))
z[]
#> [] a
#> Levels: a b
z[, drop = TRUE]
#> [] a
#> Levels: a矩阵和数组:如果某个维度的长度为1,丢掉该维度。
a <- matrix(:, nrow = )
a[, , drop = FALSE]
#> [,] [,]
#> [,]
a[, ]
#> []数据框:如果输出是单个列,返回一个向量而非数据框。
df <- data.frame(a = :, b = :)
str(df[])
#> 'data.frame': obs. of variable:
#> $ a: int
str(df[[]])
#> int [:]
str(df[, "a", drop = FALSE])
#> 'data.frame': obs. of variable:
#> $ a: int
str(df[, "a"])
#> int [:]
$
$是个简化符号,x$y
等同于x[["y", exact = FALSE]]
。它常被用在数据框中访问变量,比如mtcars$cyl
or diamonds$carat
。
对于$常见的一个错误是,当将列名存储到一个变量,尝试并使用$和这个变量来访问数据:
var <- "cyl"
# Doesn't work - mtcars$var translated to mtcars[["var"]]
mtcars$var
#> NULL # Instead use [[
mtcars[[var]]
#> []
$与[[之间有一个重要的不同,即$支持部分匹配:
x <- list(abc = )
x$a
#> []
x[["a"]]
#> NULL
如果要禁止这种情况,可以使用全局选项warnPartialMatchDollar
为TRUE
。使用时要小心:这可能影响你加载的其他代码(比如从包中加载的代码)。
缺失值/下标越界
当下标越界时(OOB),[和[[的行为略有不同,比如,对于一个长度为4的向量,试图取第5个元素,或者使用NA或NULL构造子集:
x <- :
str(x[])
#> int NA
str(x[NA_real_])
#> int NA
str(x[NULL])
#> int()
下表总结了利用[和[[,在不同类型下标、下标越界情况下,构造原子向量和列表子集的结果。
操作符 | 下标 | 原子向量 | 列表 |
[ |
OOB | NA |
list(NULL) |
[ |
NA_real_ |
NA |
list(NULL) |
[ |
NULL |
x[0] |
list(NULL) |
[[ |
OOB | Error | Error |
[[ |
NA_real_ |
Error | NULL |
[[ |
NULL |
Error | Error |
如果输入向量是命名的,那么下标越界、缺失值或者NULL,对应结果的名称为"<NA>"
。
测试
- 给定一个线性模型,比如
mod <- lm(mpg ~ wt, data = mtcars)
,提取残差的自由度。从模型摘要(summary(mod)
)中提取R squared。
构造子集和赋值
所有子集构造符都可以与赋值操作联合使用,来修改输入变量指定的值。
x <- :
x[c(, )] <- :
x
#> [] # The length of the LHS needs to match the RHS
x[-] <- :
x
#> [] # Note that there's no checking for duplicate indices
x[c(, )] <- :
x
#> [] # You can't combine integer indices with NA
x[c(, NA)] <- c(, )
#> Error in x[c(, NA)] <- c(, ): NAs are not allowed in subscripted assignments
# But you can combine logical indices with NA
# (where they're treated as false).
x[c(T, F, NA)] <-
x
#> [] # This is mostly useful when conditionally modifying vectors
df <- data.frame(a = c(, , NA))
df$a[df$a < ] <-
df$a
#> [] NA
利用空来构造子集,并联合使用赋值操作比较有用,因为这会保留原始对象的类和结构。比较下列2个表达式。第一个,mtcars
仍然是一个数据框。第二个,mtcars
变成了一个列表。
mtcars[] <- lapply(mtcars, as.integer)
mtcars <- lapply(mtcars, as.integer)
对于列表,可以联合使用构造子集、赋值、NULL来移除列表的一部分。利用[和list(NULL)
添加一个字符NULL到列表中:
x <- list(a = , b = )
x[["b"]] <- NULL
str(x)
#> List of
#> $ a: num y <- list(a = )
y["b"] <- list(NULL)
str(y)
#> List of
#> $ a: num
#> $ b: NULL
应用
利用上述基本规则,可以创建很多有用的应用。下列描述的是一些最重要的应用。其中一些基本的技巧已经包装到了更加准确的函数中(比如subset(),
merge()
,plyr::arrange()
),但是理解其中的构造子集原理是很有用的。这样当你遇到新的情况而现有函数无法解决时,你知道该怎么做。
查阅表(字符构造子集)
字符匹配是创建查询表的一种强大方式。比如你要转换缩略词:
x <- c("m", "f", "u", "f", "f", "m", "m")
lookup <- c(m = "Male", f = "Female", u = NA)
lookup[x]
#> m f u f f m m
#> "Male" "Female" NA "Female" "Female" "Male" "Male"
unname(lookup[x])
#> [] "Male" "Female" NA "Female" "Female" "Male" "Male" # Or with fewer output values
c(m = "Known", f = "Known", u = "Unknown")[x]
#> m f u f f m m
#> "Known" "Known" "Unknown" "Known" "Known" "Known" "Known"
如果不想要结果中的名称,使用unname()
将其移出。
手动匹配和合并(整形构造子集)
你可能有一个更加复杂的查询表,它包含多个列。假设我们有一个成绩向量,以及一个描述成绩属性的数据框:
grades <- c(, , , , ) info <- data.frame(
grade = :,
desc = c("Excellent", "Good", "Poor"),
fail = c(F, F, T)
)
我们想复制信息表,需要对于grades中每个值创建一行。有2种方式实现,一是使用match()和整形构造子集,或者使用rownames和字符构造子集:
grades
#> [] # Using match
id <- match(grades, info$grade)
info[id, ]
#> grade desc fail
#> Poor TRUE
#> Good FALSE
#> 2.1 Good FALSE
#> Excellent FALSE
#> 3.1 Poor TRUE # Using rownames
rownames(info) <- info$grade
info[as.character(grades), ]
#> grade desc fail
#> Poor TRUE
#> Good FALSE
#> 2.1 Good FALSE
#> Excellent FALSE
#> 1.1 Poor TRUE
如果有多个列需要匹配,你需要将它们折叠到一个单独的列(使用interaction()
,paste()
或者 plyr::id()
)。也可以用merge()或者
plyr::join(),作用是一样的——要了解如何实现的可以查阅源代码。
随机取样/放回取样(整数构造子集)
对向量和数据框,可以使用整数下标实现随机取样或者有放回取样。sample()
生成一个下标向量,然后构造子集来访问相应值:
df <- data.frame(x = rep(:, each = ), y = :, z = letters[:]) # Set seed for reproducibility
set.seed() # Randomly reorder
df[sample(nrow(df)), ]
#> x y z
#> d
#> b
#> e
#> c
#> a
#> f
# Select random rows
df[sample(nrow(df), ), ]
#> x y z
#> b
#> f
#> c
# Select bootstrap replicates
df[sample(nrow(df), , rep = T), ]
#> x y z
#> c
#> d
#> 4.1 d
#> a
#> 4.2 d
#> 3.1 c
sample()的参数控制取样的数量,以及是否是有放回取样。
排序(整数构造子集)
order()以向量为输入,返回一个整形向量,该整形向量描述了该向量应该如何排序:
x <- c("b", "c", "a")
order(x)
#> []
x[order(x)]
#> [] "a" "b" "c"
为断绝关系,你可以在order()中使用额外的变量,还可以使用decreasing = TRUE
将升序修改为降序。缺省情况下,所有缺省值会被放在向量最后;然而可以使用na.last = NA
移除缺省值,或者使用na.last = FALSE
将缺省值放在前面。
对于2维和高维数据结构,利用order()
和整形构造子集,可以方便的按照对象的行或者列排序:
# Randomly reorder df
df2 <- df[sample(nrow(df)), :]
df2
#> z y x
#> c
#> a
#> b
#> d
#> f
#> e df2[order(df2$x), ]
#> z y x
#> a
#> b
#> c
#> d
#> f
#> e
df2[, order(names(df2))]
#> x y z
#> c
#> a
#> b
#> d
#> f
#> e
sort()可以更准确对向量排序,但是不够灵活,同样plyr::arrange()可以
对数据框进行更准确的排序,但是同样不够灵活。
扩展合计数量(整形构造子集)
有时你会得到这样一个数据框,它的相同的行被折叠到了一行,并且有一列表明行的数量。rep()和整形构造子集可以很容易将折叠的数据分开,这通过一个重复的行索引实现:
df <- data.frame(x = c(, , ), y = c(, , ), n = c(, , ))
rep(:nrow(df), df$n)
#> []
df[rep(:nrow(df), df$n), ]
#> x y n
#>
#> 1.1
#> 1.2
#>
#> 2.1
#> 2.2
#> 2.3
#> 2.4
#>
移除数据框的列(字符构造子集)
有2种方式从数据框中移除列。可以通过将某一列设置为NULL来实现:
df <- data.frame(x = :, y = :, z = letters[:])
df$z <- NULL
或者可以通过构造子集来获取想要的列:
df <- data.frame(x = :, y = :, z = letters[:])
df[c("x", "y")]
#> x y
#>
#>
#>
如果你知道哪些列是不需要的,可以使用设置操作来得到想要的列:
df[setdiff(names(df), "z")]
#> x y
#>
#>
#>
根据条件选择行(逻辑构造子集)
因为可以方便的合并多个列的条件,所以逻辑构造子集可能是提取数据框行的最常用方式。
mtcars[mtcars$gear == , ]
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> 26.0 120.3 4.43 2.140 16.7
#> 30.4 95.1 3.77 1.513 16.9
#> 15.8 351.0 4.22 3.170 14.5
#> 19.7 145.0 3.62 2.770 15.5
#> 15.0 301.0 3.54 3.570 14.6
mtcars[mtcars$gear == & mtcars$cyl == , ]
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> 26.0 120.3 4.43 2.140 16.7
#> 30.4 95.1 3.77 1.513 16.9
记得使用&和|,而不是&&和||,&&和||在条件语句中更加有用。不要忘记摩根定律(De Morgan’s laws),它可以用来简化否定:
!(X & Y)
等同于!X | !Y
!(X | Y)
等同于!X & !Y
例如,!(X & !(Y | Z))
可以简化为!X | !!(Y|Z)
,进一步简化为!X | Y | Z
。
subset()是一个特殊的简化了的构造数据框子集的函数,用它可以少敲几下键盘,因为不需要重复数据框的名字。你将在非标准计算(non-standard evaluation)中看到它是如何工作的。
subset(mtcars, gear == )
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> 26.0 120.3 4.43 2.140 16.7
#> 30.4 95.1 3.77 1.513 16.9
#> 15.8 351.0 4.22 3.170 14.5
#> 19.7 145.0 3.62 2.770 15.5
#> 15.0 301.0 3.54 3.570 14.6
subset(mtcars, gear == & cyl == )
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> 26.0 120.3 4.43 2.140 16.7
#> 30.4 95.1 3.77 1.513 16.9
布尔代数与设置操作(逻辑和整形构造子集)
需要注意设置操作(整形构造子集)与布尔代数(布尔构造子集)之间的等效性。在某些情况下使用设置操作更加有效:
试图找出第一个(或者最后一个)
TRUE
。当有比较少的
TRUE
s和非常多的FALSE
s;设置操作可能更快而且需要更少的内存。
which()
可以将一个逻辑表示转换为整形表示。基础R中没有反转操作但是可以很容易创建一个:
x <- sample() <
which(x)
#> [] unwhich <- function(x, n) {
out <- rep_len(FALSE, n)
out[x] <- TRUE
out
}
unwhich(which(x), )
#> [] FALSE FALSE TRUE FALSE FALSE FALSE TRUE FALSE FALSE TRUE
让我们来创建2个逻辑向量和对等的整形向量,然后看下布尔值与设置操作的关系。
(x1 <- : %% == )
#> [] FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE
(x2 <- which(x1))
#> []
(y1 <- : %% == )
#> [] FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE TRUE
(y2 <- which(y1))
#> [] # X & Y <-> intersect(x, y)
x1 & y1
#> [] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE
intersect(x2, y2)
#> [] # X | Y <-> union(x, y)
x1 | y1
#> [] FALSE TRUE FALSE TRUE TRUE TRUE FALSE TRUE FALSE TRUE
union(x2, y2)
#> [] # X & !Y <-> setdiff(x, y)
x1 & !y1
#> [] FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE FALSE
setdiff(x2, y2)
#> [] # xor(X, Y) <-> setdiff(union(x, y), intersect(x, y))
xor(x1, y1)
#> [] FALSE TRUE FALSE TRUE TRUE TRUE FALSE TRUE FALSE FALSE
setdiff(union(x2, y2), intersect(x2, y2))
#> []
开始学习构造子集时的一个常见错误是使用x[which(y)]
替代x[y]
。这儿which()
什么都没干:它将逻辑构造子集转换成整形构造子集,但是结果完全一样。同样要注意x[-which(y)]
并不等同于x[!y]
:如果y全是FALSE,which(y)
会得到integer(0),而
integer(0)
还是integer(0)
,所以你没有获取任何值,而不是所有值。通常应该避免将逻辑构造子集转换成整形构造子集,除非你想这么做,比如获取第一个或者最后一个TRUE。
练习
- 如何随机排列数据框中的列?(在随机预测中这很重要。)你能否在一步内同时随机排列行和列?
- 如何随机选取数据框中的m行?如果要求这m行是连续的那(比如,一个首行,一个结束行,以及其中所有的行)?
- 如何将数据框的列按照字母表排序?
答案
- 正整数选取对应位置的元素,负整数去除对应位置的元素;逻辑向量保留TRUE对应位置的元素;字符向量按照名称匹配选取元素。
- [选取子列表。它总是得到一个列表;如果使用[和一个正整数来构造子集,会得到一个长度为1的列表。[[选取列表中的元素。$是为了方便起见的缩写符号:
x$y
等同于x[["y"]]
。 - 如果构造矩阵、数据或者数据框的子集时,想保留数据结构,使用
drop = FALSE
。在函数内容构造子集时,你应该总是这么做。 - 如果x是矩阵,
x[] <- 0
将替换每个元素为0,行和列的数量不变,x <- 0
会将矩阵替换为0。 - 一个命名的向量可以作为一个简单的查询表:
c(x = 1, y = 2, z = 3)[c("y", "z", "x")]
。
Advanced R之构造子集的更多相关文章
- Advanced R之函数
转载请注明出处,谢谢. 再次声明下,本人水平有些,错误之处敬请指正. 函数 函数是R基本的块结构单元:为了掌握本书中的更高级技术,你需要对函数有扎实的了解.也许你已经写过一些函数,并了解函数的基本知识 ...
- Advanced R之数据结构
看了几本R语言语法相关的书籍,感觉都不怎么好,在实际使用过程中仍然遇到很多难以理解的问题,后来看了Hadley Wickham的Advanced R,好多问题迎刃而解,今天重温了该书的第一章即数据结构 ...
- R语言︱构造新序列
1.数值构造函数rep与seq #数值构造rep与seq rep(1:4,each=2)#依次重复1:4两遍 rep(1:4,2) #注意,重复1:4两遍 seq(from=3,to=5,by=0.2 ...
- Advanced R之编程风格
转载请注明出处,谢谢. 编程风格指导 好的编码风格如同正确使用标点符号一样重要.没有编码规范仍然可以管理代码,但是有代码规范会使代码更易阅读.如同标点样式,编码规范也有不同.下面描述的是我所使用的 ...
- Advanced R之词汇表
转载请注明出处:http://www.cnblogs.com/lizichao/p/4800513.html 词汇表 想要玩得转R,重要的一点是有一个好的工作词汇表.以下是我认为的一个好的词汇表.你不 ...
- 【翻译】R 中的设计模式
目录 R 中的设计模式 不动点算法 包装器模式 接口模式 柯里化(Currying) 闭包(Closures) 缓存模式 计数器模式 R 中的设计模式 本文翻译自 Design Patterns in ...
- 【计理05组01号】R 语言基础入门
R 语言基本数据结构 首先让我们先进入 R 环境下: sudo R 赋值 R 中可以用 = 或者 <- 来进行赋值 ,<- 的快捷键是 alt + - . > a <- c(2 ...
- 【翻译】Awesome R资源大全中文版来了,全球最火的R工具包一网打尽,超过300+工具,还在等什么?
0.前言 虽然很早就知道R被微软收购,也很早知道R在统计分析处理方面很强大,开始一直没有行动过...直到 直到12月初在微软技术大会,看到我软的工程师演示R的使用,我就震惊了,然后最近在网上到处了解和 ...
- 轻松创建R语言函数包
讲真,用R这么几年,始终未尝试过写自己的包,看来这就是我与真正程序员的差距了——编程习惯等于没有. 昨天一个偶然的机会想开始写自己的工具包,发现了前期教程的有一些过时.于是,写一个**windows* ...
随机推荐
- PHP进阶知识
关于PHP程序员技术职业生涯规划:http://rango.swoole.com/ Micro Service Framework For PHP:https://github.com/pinguo/ ...
- java.lang.NoSuchMethodError: org.jboss.logging.Logger.getMessageLogger(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Object;
spring3_hibernate 集成报错信息 java.lang.NoSuchMethodError: org.jboss.logging.Logger.getMessageLogger(Ljav ...
- EasyPlayerPro windows播放器本地配置文件配置方法介绍
需求背景 应EasyPlayerPro某客户需求,在EasyPlayerPro启动时,自动播放指定的url源, 不需要每次都去手动填写, 且实现自动播放,不需要手动的单击播放按钮: 为响应该需求,特增 ...
- redis自启动
$ vi /etc/init.d/redis # chkconfig: 2345 90 10 # description: Redis is a persistent key-value databa ...
- JavaEE与Spring
在Java社区中,Spring与Java EE之争是个永恒的话题.在这场争论中,来自两个阵营的布道师.架构师与铁杆粉丝都在不遗余力地捍卫着本方的尊严,并试图说服对方加入到自己的阵营当中,但结果却是双方 ...
- Django创建项目及app
主要环境为python3.5,编译环境为pycharm 首先已经安装好Django相关的组件 1.首先创建Django程序: windows系统下pycharm创建步骤: File->New P ...
- 在RedHat Linux系统中安装和配置snmp服务
检查系统是否安装snmp服务 # rpm -qa|grep snmp net-snmp-5.3.2.2-17.el5 net-snmp-perl-5.3.2.2-17.el5 net-snmp-dev ...
- 常见C C++问题(转)
这一部分是C/C++程序员在面试的时候会被问到的一些题目的汇总.来源于基本笔试面试书籍,可能有一部分题比较老,但是这也算是基础中的基础,就归纳归纳放上来了.大牛们看到一笑而过就好,普通人看看要是能补上 ...
- Kaggle系列1:手把手教你用tensorflow建立卷积神经网络实现猫狗图像分类
去年研一的时候想做kaggle上的一道题目:猫狗分类,但是苦于对卷积神经网络一直没有很好的认识,现在把这篇文章的内容补上去.(部分代码参考网上的,我改变了卷积神经网络的网络结构,其实主要部分我加了一层 ...
- github 博客模板
http://www.jianshu.com/p/d658ba3b4351 http://jekyllthemes.org/