2016-11-08 57 views
1

我覺得我對data.frames及其工作方式有了很好的理解,但列表的某些方面讓我感到困惑。瞭解列表行爲

下面是一些重複性的數據開始:

list_a <- structure(list(`one` = structure(list(
    words = c("a", "b","c", "d", "e", "f")), .Names = "words", class = "data.frame", row.names = c(NA,-6L)), 
    `two` = structure(list(words = c("a","s","t","z")), .Names = "words", class = "data.frame", row.names = c(NA, -4L))), 
    .Names = c("one", "two")) 

這給我們:

list_a 
$one 
    words 
1  a 
2  b 
3  c 
4  d 
5  e 
6  f 

$two 
    words 
1  a 
2  s 
3  t 
4  z 

現在我想遍歷列表返回一些在data.frames結果。

list <- list() 

for(i in list_a){list <- append(list, list_a$i$words)} 

這不會在列表中產生任何結果。同樣沒有:

for(i in list_a){list <- append(list, list_a[[i]]$words)} 
Error in list_a[[i]] : invalid subscript type 'list' 

我想也許我的第一圈沒工作了,我用list_a$i$words沒有定義我爲正確的名稱的原因。所以,我想:

for(i in names(list_a)){list <- append(list, list_a$i$words)} 

這仍然讓我長的列表0

所以我不明白爲什麼嘗試我試過沒有給我希望的結果,我不知道爲什麼使用標給了我一個錯誤,我終於想通了正確的語法:使用名稱方法時沒有

for(i in list_a){list2 <- append(list2, i$words)}

但是我不知道爲什麼這個工程?

+1

不要追加到'for'循環中的對象。精簡預分配(或使用循環函數,例如'lapply'來爲你做這件事)。無論如何,使用'我$字'而不是'list_a $ i $ words'。循環迭代列表元素,即'i'包含列表元素而不是它們的索引。 – Roland

+0

謝謝,任何有關問題質量的洞察力都是有人低估了它的,我認爲從示例數據到清晰度我已勾選了所有框? – Olivia

回答

0

的參數R中的for表達包括:

  • LHS,迭代器,將帶RHS
  • 的每個值
  • in,語言關鍵字
  • RHS,的載體,其長度其中定義了將發生的迭代次數。

設置第一個循環時,RHS是類型爲「list」的長度爲2的向量。在LHS上,您有一列數據框i。然後,您要求$從list_a中提取「i」,其值爲NULL。在你的第二個循環中,RHS是一個長度爲2的「字符」類型的向量。同樣的事情發生了。

$未評估其索引。改爲使用[[,您將在第二個循環中得到您期望的答案。

# initialize 
list <- list() 
# loop 
for (i in names(list_a)) { 
    list <- append(list, list_a[[i]]$words) 
} 
list 
# [[1]] 
# [1] "a" 
# 
# [[2]] 
# [1] "b" 
# ... 

如由Roland提到的那樣,追加是R中非常昂貴的,因爲每次迭代創建該對象的新副本。這裏是一個另類嘗試:

# create a data frame using all of list_a, 
# coerce to character vector 
# then coerce to list 
as.list(unname(unlist(do.call(what = "rbind", args = list_a)))) 

注意,「data.frame」的對象只是「名單」應用了「data.frame」類屬性的對象。因此,在使用data.frames和$時,您將看到與列表一樣的未評估名稱時的相同行爲。試試這個:

# print mtcars data.frame 
mtcars 
# set class attribute to NULL 
class(mtcars) <- NULL 
# mtcars is just a list now :-) 
mtcars 

編輯:$[[是運營商,這只是意味着他們可以以特殊的方式來使用的功能。你也可以像普通函數一樣使用它們,將它們的參數傳遞給圓括號。

# $ is a function 
`$`(list_a, "one") 
# words 
# 1  a 
# 2  b 
# ... 

這些函數的行爲是不同的。 [[需要它解釋的一個對象。 $需要它嘗試查找的元素名稱。

i <- "one" 
# $ is a function, but there is no element "i" 
`$`(list_a, i) 
# NULL 
# [[ is a function, and an element "one" is present 
`[[`(list_a, i) 
# words 
# 1  a 
# 2  b 
# ... 
+0

您可以更多地解釋'$'vs'[[]]'。爲什麼'list_a $ i $ words'評估爲'NULL',但是'i $ words'在兩種情況下都是正確的,我們確實在看'list_a'? – Olivia

+0

@Olivia編輯回覆,附加說明。這是否使事情更清楚? – CSJCampbell

+0

非常感謝! – Olivia