在循环中追加/合并到R中的向量

时间:2015-10-18 21:24:34

标签: r loops web-scraping

我正在从多个网站Link here抓取数据并尝试将所有这些数据合并到一个数据框中。这些网站有一个反复出现的模式,所以我尝试了在一个地方获取链接然后迭代for循环: 这是我正在处理的代码块:

ingredientsList = c()
links<-paste0("http://www.bbc.co.uk/food/ingredients/by/letter/",letters)
#prints out:
#http://www.bbc.co.uk/food/ingredients/by/letter/a
#http://www.bbc.co.uk/food/ingredients/by/letter/b
#http://www.bbc.co.uk/food/ingredients/by/letter/c and so-on till z
for(i in 1:26){
    session<-html_session(links[i])
    ingredients<-session %>% html_nodes("ol:nth-child(4) a") %>% html_text()
    ingredientsList<-c(ingredientsList,ingredients)
}

结果是 ingredientList ,理想情况下应该包含从'A'到'Z'的所有成分的列表 我正在努力学习R和相当新的刮,我真的很感激一些指导。感谢。

1 个答案:

答案 0 :(得分:1)

您最好使用list代替vector,并且可以使用lapply直接创建它,如下所示:

library(rvest)
library(stringr)

url <- "http://www.bbc.co.uk/food/ingredients/by/letter/"
urls <- paste0(url, letters)

ingredientsList <- lapply(urls, function(u) { 
  u %>%
    html_session() %>%
    html_nodes("ol:nth-child(4) a") %>%
    html_text() %>%
    str_replace_all(pattern = "\n|Related|\\(\\d\\)|\\s{2,}", replacement  = "") %>% ## clean results (remove space, etc)
    subset(!str_detect(., "^\\s{1}")) 
})

names(ingredientsList) <- LETTERS
str(ingredientsList)
## List of 26
##  $ A: chr [1:33] "Acidulated water" "Ackee" "Acorn squash" "Aduki beans" ...
##  $ B: chr [1:101] "Bacon" "Bagel" "Baguette" "Baked beans" ...
##  $ C: chr [1:174] "Cabbage" "Caerphilly" "Cake" "Calasparra rice" ...
##  $ D: chr [1:31] "Dab" "Daikon" "Damsons" "Dandelion" ...
##  $ E: chr [1:15] "Edam" "Eel" "Egg" "Egg liqueur" ...
##  $ F: chr [1:50] "Farfalle" "Fat" "Fennel" "Fennel seeds" ...
##  $ G: chr [1:53] "Galangal" "Game" "Gammon" "Garam masala" ...
##  $ H: chr [1:30] "Habañero chillies" "Haddock" "Haggis" "Hake" ...
##  $ I: chr [1:5] "Ice cream" "Iceberg lettuce" "Icing" "Icing sugar" ...
##  $ J: chr [1:12] "Jaggery" "Jam" "January King cabbage" "Japanese pumpkin" ...
##  $ K: chr [1:12] "Kabana" "Kale" "Ketchup" "Ketjap manis" ...
##  $ L: chr [1:49] "Lager" "Lamb" "Lamb breast" "Lamb chop" ...
##  $ M: chr [1:76] "Macadamia" "Macaroni" "Macaroon" "Mace" ...
##  $ N: chr [1:14] "Naan bread" "Nachos" "Nashi" "Nasturtium" ...
##  $ O: chr [1:20] "Oatcakes" "Oatmeal" "Oats" "Octopus" ...
##  $ P: chr [1:109] "Paella" "Pak choi" "Palm sugar" "Pancakes" ...
##  $ Q: chr [1:6] "Quail" "Quail's egg" "Quark" "Quatre-épices" ...
##  $ R: chr [1:62] "Rabbit" "Rack of lamb" "Radicchio" "Radish" ...
##  $ S: chr [1:125] "Safflower oil" "Saffron" "Sage" "Salad" ...
##  $ T: chr [1:47] "T-bone steak" "Tabasco" "Taco" "Tagliatelle" ...
##  $ U: chr "Unleavened bread"
##  $ V: chr [1:18] "Vacherin" "Vanilla essence" "Vanilla extract" "Vanilla pod" ...
##  $ W: chr [1:38] "Waffles" "Walnut" "Walnut oil" "Wasabi" ...
##  $ X: chr(0) 
##  $ Y: chr [1:4] "Yam" "Yeast" "Yellow lentil" "Yoghurt"
##  $ Z: chr [1:2] "Zander" "Zest"

或者我们可以使用类似于您的方法for循环

n <- length(letters)
ingredientsList <- vector(mode = "list", length = n)
names(ingredientsList) <- LETTERS

for(i in 1:n) {
    session<-html_session(urls[i])
    ingredientsList[[i]] <-session %>% 
                           html_nodes("ol:nth-child(4) a") %>% 
                           html_text()
}

但技巧是坚持使用list来保持你的结果。