2016-12-30 29 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