2016-12-30 297 views
0

我读过使用seq_along()可以更好地处理空案例,但这个概念在我的脑海中并不那么清楚。使用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 

考虑这三种不同的代码片断:

# 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)) 

是什么,这些不同的程序之间的差异时,一个完整的data.frame存在或存在空的data.frame

+2

你为什么不看自己使用'DF <为 - data.frame()' –

回答

1

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

案例1个牺牲品......

错误.subset2(X,I,准确=准确):标出来的边界

案例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 

本质上,的每个元素矢量a,有一个由seq_along创建的相应索引被访问。

如果我们在上述情况下,现在申请seq_along向空df,我们得到:

seq_along(df) 
# integer(0) 

因此,那些被创造是一个零长度向量。它很难沿零长度向量移动。

因此,这个案例1不佳保护的反对空的情况下

现在,传统的假设下,即存在data.frame,这是一个非常糟糕的假设任何种类的开发,使之内的一些数据...

set.seed(1234) 
df <- data.frame(matrix(rnorm(40), 4)) 

所有案件将按预期运作。也就是说,您会收到data.frame的每列中位数。

[1] -0.5555419 
[1] -0.4941011 
[1] -0.4656169 
[1] -0.605349 
+0

这可能是值得在你的答案指出'1:NcoI位(DF)'一个空的数据帧与'1:0'一样,它输出两个元素向量'c(0,1)',而不是像其他两个例子那样输出一个空向量。 – Barker

+0

@巴克,好点。更新。 – coatless