G. B.

个人博客

且将新火试新茶,诗酒趁年华


子集选取

子集选取

数据类型

值得注意的只有 S3 对象和 S4 对象

  • S3 对象是由 atomic vector、array 和 list 组成的,常用方法即可
  • S4 对象要用到@(等价于$)和slot()(等价于[[

子集选取运算符

###

df <- data.frame(x=1:3,y=I(list(1:2,1:3,1:4)))
df[1,,drop=FALSE]
#>   x    y
#> 1 1 1, 2

df[1,,drop=TRUE]
#> $x
#> [1] 1
#>
#> $y
#> $y[[1]]
#> [1] 1 2

加入drop=TRUE选项会去除维度

###

x$y等价于x[["y",exact = FALSE]]$是部分匹配的,也就是说不用完整的写出某一列的名称,只要首字母或首几位即可。

df<-data.frame(first=1:3,second=I(list(1:2,1:3,1:4)))
df$f
#> [1] 1 2 3
df$s
#> [[1]]
#> [1] 1 2
#>
#> [[2]]
#> [1] 1 2 3
#>
#> [[3]]
#> [1] 1 2 3 4

可以通过设置options(warnPartialMatchDollar = TRUE)来关闭部分匹配,但不推荐。

###

子集选取时使用空引用再结合赋值操作会比较有用,因为它会保持原有的对象类和数据结构不会遭到破坏。

mtcars[] <- lapply(mtcars,as.integer)  # 结果还是dataframe
mtcars <- lapply(mtcars,as.integer)  # 结果变成了list

应用

###

构建查询表

x <- c("m","f","u","f","f","m","m")
lookup <- c(m="male",f="female",u=NA)
unname(lookup[x])

###

注意each参数

rep(1:3,each=3)
#> [1] 1 1 1 2 2 2 3 3 3
rep(1:3,3)
#> [1] 1 2 3 1 2 3 1 2 3

###

setdiff(x,y)为从 x 中删掉 y

###

分清逻辑运算符和短路运算符

类别 运算符 适用类型
逻辑运算符 & | ! 适用于向量
短路运算符 && || ! 适用于标量,条件语句 if

例: a<1 & b>1a<1 && b>1

逻辑运算符会将两侧表达式都计算一遍再返回结果,短路运算符在假如左侧表达式结果为 FALSE 的情况下停止计算,因为此时不论右侧结果是什么,整体结果都会是 FALSE

德-摩根定理

  • !(x & y) 等价于 !x | !y
  • !(x | y) 等价于 !x & !y
  • !(x & !(y | z)) 等价于 !x | !!(y | z) 等价于 !x | y | z

###

  • x & y 等价于 intersect(x,y)
  • x | y 等价于 union(x,y) # union()会自动去重
  • x & !y 等价于 setdiff(x,y) # 从 x 中删除 y
  • xor(x,y) 等价于 setdiff(union(x,y),intersect(x,y)) # 从 x|y 中删除 x&y 的部分