2011-09-21 45 views
4

可以說,RES是一個容量爲1000個結構的列表,kmeans可以生成輸出結果。如何使用R自動創建結構列表?

我該如何聲明RES?

有RES後宣佈我想要做這樣的事情:

for (i in 1:1000) { 
    RES[i] = kmeans(iris,i) 
} 

謝謝。 Rui

回答

1

創建列表的方式不同於創建數值向量的常用方式。

# The "usual" way to create a numeric vector 
myNumVec <- numeric(1000) # A numeric vector with 1000 zeroes... 

# ...But there is also this way 
myNumVec <- vector("numeric", 1000) # A numeric vector with 1000 zeroes... 


# ...and that's the only way to create lists: 

# Create a list with 1000 NULLs 
RES <- vector("list", 1000) 

所以,你的例子會成爲,

RES <- vector("list", 1000) 
for (i in 1:1000) { 
    RES[[i]] = kmeans(iris,i) 
} 

(請注意,k均值不喜歡與虹膜數據直接設置一樣,雖然被稱爲...)

但隨後再次,lapply也會這樣做,並且以@Andrie所示的更直接的方式。

+0

在你的例子中,我們知道這是類型「數字」 我不知道什麼類型是kmeans函數輸出。我想這是類似於「C」中的結構。我該如何解決這個問題? THanks – Rui

+0

@Rui'kmeans'的輸出是類「kmeans」的一個對象,它基本上與列表相同。所以@Tmymy的代碼將起作用(除了kmeans需要一個距離矩陣作爲輸入,而不是data.frame)。 – Andrie

+0

@ Andrie,我從來沒有用距離矩陣作爲輸入的kmeans。我總是使用一個data.frame。 sapply/lapply解決方案非常優雅。謝謝 – Rui

4

如果您使用R適用成語,你的代碼會更簡單,你不必聲明您的變量提前:

RES <- lapply(1:3, function(i)kmeans(dist(iris[, -5]),i)) 

結果:

> str(RES) 
List of 3 
$ :List of 7 
    ..$ cluster  : Named int [1:150] 1 1 1 1 1 1 1 1 1 1 ... 
    .. ..- attr(*, "names")= chr [1:150] "1" "2" "3" "4" ... 
    ..$ centers  : num [1, 1:150] 2.89 2.93 3.04 2.96 2.93 ... 
    .. ..- attr(*, "dimnames")=List of 2 
    .. .. ..$ : chr "1" 
    .. .. ..$ : chr [1:150] "1" "2" "3" "4" ... 
    ..$ totss  : num 55479 
    ..$ withinss : num 55479 
    ..$ tot.withinss: num 55479 
    ..$ betweenss : num 4.15e-10 
    ..$ size  : int 150 
    ..- attr(*, "class")= chr "kmeans" 
$ :List of 7 
    ..$ cluster  : Named int [1:150] 1 1 1 1 1 1 1 1 1 1 ... 
    .. ..- attr(*, "names")= chr [1:150] "1" "2" "3" "4" ... 
    ..$ centers  : num [1:2, 1:150] 0.531 4.104 0.647 4.109 0.633 ... 
    .. ..- attr(*, "dimnames")=List of 2 
    .. .. ..$ : chr [1:2] "1" "2" 
    .. .. ..$ : chr [1:150] "1" "2" "3" "4" ... 
    ..$ totss  : num 55479 
    ..$ withinss : num [1:2] 863 9743 
    ..$ tot.withinss: num 10606 
    ..$ betweenss : num 44873 
    ..$ size  : int [1:2] 51 99 
    ..- attr(*, "class")= chr "kmeans" 
$ :List of 7 
    ..$ cluster  : Named int [1:150] 2 2 2 2 2 2 2 2 2 2 ... 
    .. ..- attr(*, "names")= chr [1:150] "1" "2" "3" "4" ... 
    ..$ centers  : num [1:3, 1:150] 3.464 0.5 5.095 3.438 0.622 ... 
    .. ..- attr(*, "dimnames")=List of 2 
    .. .. ..$ : chr [1:3] "1" "2" "3" 
    .. .. ..$ : chr [1:150] "1" "2" "3" "4" ... 
    ..$ totss  : num 55479 
    ..$ withinss : num [1:3] 2593 495 1745 
    ..$ tot.withinss: num 4833 
    ..$ betweenss : num 50646 
    ..$ size  : int [1:3] 62 50 38 
    ..- attr(*, "class")= chr "kmeans" 
+0

尼斯:) 然而,我試圖 RES < - sapply(1:3,功能(I)k均值(光圈[,-5],i))的 我得到這個錯誤:錯誤:數聚類中心的必須位於1和nrow之間(x) THanks – Rui

+0

這是因爲您試圖聚集在「虹膜」上,而不是距離矩陣。閱讀「kmeans」和「?dist」的幫助。 – Andrie

+0

謝謝Andrie。這是因爲kmeans。現在你的解決方案正在工作我學會了一些重要的事情! – Rui

2

我會其次lapply在這種情況下是正確的答案。 但有很多情況下需要循環,這是一個很好的問題。

R裏面,列表不需要被聲明爲空的時間提前,所以最簡單的方式做到這一點會只是「聲明」 RES爲空列表:

RES <- list() 
for (i in 1:1000) { 
    RES[i] = kmeans(iris,i) 
} 

R將只延長列表爲每個迭代。

順便提及,這個工程即使對於非順序索引:

newList <- list() 
newList[5] <- 100 

產生具有狹槽1至4設計爲NULL和第五時隙100的數量的列表。

這只是說,列表是非常在R比不同的野獸比原子載體。

+0

謝謝大家!它以幾種方式工作:) – Rui