使用 seq_along() 处理空情况

Fra*_*ddu 6 r seq is-empty

我读到使用seq_along()可以更好地处理空的情况,但这个概念在我的脑海中并不是那么清晰。

例如,我有这个数据框:

df
            a            b          c          d
1   1.2767671  0.133558438  1.5582137  0.6049921
2  -1.2133819 -0.595845408 -0.9492494 -0.9633872
3   0.4512179  0.425949910  0.1529301 -0.3012190
4   1.4945791  0.211932487 -1.2051334  0.1218442
5   2.0102918  0.135363711  0.2808456  1.1293810
6   1.0827021  0.290615747  2.5339719 -0.3265962
7  -0.1107592 -2.762735937 -0.2428827 -0.3340126
8   0.3439831  0.323193841  0.9623515 -0.1099747
9   0.3794022 -1.306189542  0.6185657  0.5889456
10  1.2966537 -0.004927108 -1.3796625 -1.1577800
Run Code Online (Sandbox Code Playgroud)

考虑这三个不同的代码片段:

# Case 1
for (i in 1:ncol(df)) {
    print(median(df[[i]]))
}

# Case 2
for (i in seq_along(df)) {
    print(median(df[[i]]))
}

# Case 3
for(i in df) print(median(i))
Run Code Online (Sandbox Code Playgroud)

data.frame当存在 full 或存在empty时,这些不同的过程有什么区别data.frame

coa*_*ess 4

在 的条件下df <- data.frame(),我们有:

案例1受害人...

.subset2(x,i,exact =exact)中的错误:下标超出范围

情况2和情况3则不会被触发。

本质上,情况 1中的错误是由于ncol(df)0这导致序列1:ncol(df)1:0,从而创建向量c(1,0)。在这种情况下,for循环尝试访问向量 的第一个元素1,该元素尝试访问不存在的列 1 。因此,发现该子集超出范围。

同时,在情况 2 和情况 3中,循环永远不会执行,因为向量为for,因此在各自的集合内没有要处理的元素。原则上,这意味着它们的长度为。0

由于这个问题具体涉及到底发生了什么seq_along(),让我们seq_along通过构建一个完整的向量a并查看结果来举一个传统的例子:

set.seed(111)
a <- runif(5)
seq_along(a)
#[1] 1 2 3 4 5
Run Code Online (Sandbox Code Playgroud)

本质上,对于向量的每个元素a,都有一个相应的索引来创建以供seq_along访问。

如果我们现在应用到上述情况中的seq_along空,我们会得到:df

seq_along(df)
# integer(0)
Run Code Online (Sandbox Code Playgroud)

因此,创建的是一个零长度向量。沿着零长度向量移动非常困难。

因此,案例 1 对于空案例的保护效果很差

现在,在传统的假设下,即 中有一些数据,这对于任何类型的开发人员来说data.frame都是一个非常糟糕的假设......

set.seed(1234)
df <- data.frame(matrix(rnorm(40), 4))
Run Code Online (Sandbox Code Playgroud)

所有三个案例都将按预期运行。也就是说,您将收到 的每列的中位数data.frame

[1] -0.5555419
[1] -0.4941011
[1] -0.4656169
[1] -0.605349 
Run Code Online (Sandbox Code Playgroud)