子集运算规律

本文详细介绍了R语言中子集运算符[]和$的使用方法,包括它们在列表和dataframe中的区别,部分匹配特性,以及如何处理缺失值和进行赋值操作。同时,讨论了如何通过[]和赋值操作保持对象的原始类和结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

《Advanced R》

最常用的子集运算符是[],除此之外还有[[]]$

首先[[]]

[[]][]用法类似,不同的是[[]]可以从列表中取子集,而且它只能返回single value

由于data frame是由一列一列的list构成的,固然也可以使用[[]]来提取列

[]用于list,返回的结果也是list形式,而用[[]]可以直接得到其内容(打破list框架)
举个例子:如果list x 是一辆火车,那么x[[5]]是5号车厢中的乘客,而x[5]是5号车厢

a <- list(a = 1, b = 2)
a[[1]]
#> [1] 1
a[["a"]]
#> [1] 1

# 如果你提供一个向量,它会循环索引
b <- list(a = list(b = list(c = list(d = 1))))
b[[c("a", "b", "c", "d")]]
#> [1] 1
# 同样的
b[["a"]][["b"]][["c"]][["d"]]
#> [1] 1

其次$

$是一个简化符号,x$y等同于x[["y" , exact = FALSE]]

通常用于访问data frame中的列,即variables

$只能用列名直接提取,而不能用储存在变量中的列名去提取

var <- "cyl"
# Doesn't work - mtcars$var translated to mtcars[["var"]]
mtcars$var
#> NULL

但是[[]]可以

mtcars[[var]]
#>  [1] 6 6 4 6 8 6 8 4 4 6 6 8 8 8 8 8 8 4 4 4 4 8 8 8 8 4 4 4 8 6 8 4

此外[[]]$还有一个重要区别
$可以进行部分匹配

x <- list(abc = 1)
x$a
#> [1] 1
x[["a"]]
#> NULL

当遇到缺失值NA或越界索引OOB (out of bounds) 时

举例:

  • 当你尝试在长度为4的向量中提取第5个元素时;
  • 当你取带有NA或NULL的向量子集时
x <- 1:4
str(x[5])
#>  int NA
str(x[NA_real_])
#>  int NA
str(x[NULL])
#>  int(0)

子集化和赋值

所有子集运算符都可以与赋值运算符结合使用,以修改输入向量的选定值

# 赋值特定位置
x <- 1:5
x[c(1, 2)] <- 2:3
x
#> [1] 2 3 3 4 5

x[-1] <- 4:1
x
#> [1] 2 4 3 2 1

# 赋值重复位置
# 直接被覆盖
x[c(1, 1)] <- 2:3
x
#> [1] 3 4 3 2 1

# 整数混入NA,报错
x[c(1, NA)] <- c(1, 2)
#> Error in x[c(1, NA)] <- c(1, 2): NAs are not allowed in subscripted assignments
# 逻辑值混入NA,可以
# 因为NA在逻辑值中视为FALSE
x[c(T, F, NA)] <- 1
x
#> [1] 1 4 3 1 1

# 当遇到条件修改向量
df <- data.frame(a = c(1, 10, NA))
df$a[df$a < 5] <- 0
df$a
#> [1]  0 10 NA

不带任何内容的子集设置与赋值一起使用非常有用,因为它将保留原始对象类和结构。
比较以下两个表达式:

  • 在第一种情况下, mtcars 将保留为数据帧;
  • 在第二种情况下, mtcars 将成为一个列表。
mtcars[] <- lapply(mtcars, as.integer)
mtcars <- lapply(mtcars, as.integer)

对于列表,可以使用subsetting + assignment + NULL 从列表中删除组件
要将 NULL 添加到列表中,使用 [] 然后 list(NULL)

x <- list(a = 1, b = 2)
x[["b"]] <- NULL
str(x)
#> List of 1
#>  $ a: num 1

y <- list(a = 1)
y["b"] <- list(NULL)
str(y)
#> List of 2
#>  $ a: num 1
#>  $ b: NULL
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值