Попытка собрать статистику отдельных игр по карьере игрока с сайтаbasketball-reference.com (который работает), но я хочу добавить имя игрока в полученный df, соответствующий результатам отдельных игр. Например, первый цикл будет просто повторять «Карим Абдул-Джаббар» 86 раз для 86 строк, сгенерированных очисткой. Я пытаюсь добавить следующий цикл в существующий столбец с именем Player_Name, используя метод заполнения cbind, но вместо этого cbind создает новый столбец для каждого цикла. Будем очень признательны за любые советы о том, как поместить имя игрока в один столбец.
library(rvest)
library(dplyr)
# Create df of players to be scraped
#########################################################################
players = data.frame(player_name = c(rep("Kareem Abdul-Jabbar",each=20),
rep("Karl Malone",each=19)),
player_id = c(rep("abdulka01",each=20),
rep("malonka01",each=19)),
initial = c(rep("a",each=20),
rep("m",each=19)),
year = c(seq(1970,1989,by=1),
seq(1986,2004,by=1)))
# Scrape data and stack in a df
#########################################################################
output <- data_frame()
for (i in 1:2){
url <- paste0("https://www.basketball-reference.com/players/",
players[i,3],"/",players[i,2],"/gamelog/",players[i,4])
webpage <- read_html(url)
temp <- webpage %>%
html_nodes("#pgl_basic") %>%
html_table()
player_name=players[i,1]
output <- cbind(bind_rows(output, temp),player_name)
}
Я не уверен, как выглядит окончательная форма, которую вы хотите, но вы можете попробовать изменить последнюю часть своего кода.
output <- cbind(bind_rows(output, temp),player_name)
становиться
output <- bind_rows(output, temp)
output$player_name <- player_name
Есть гораздо более чистый способ решения этой проблемы с помощью функционального программирования. Сначала мы устанавливаем параметры в табличках.
library(tidyverse)
library(glue)
kareem <- tibble(
player_name = 'Kareem Abdul-Jabbar',
player_id = 'abdulka01',
initial = 'a',
year = 1970:1989)
karl <- tibble(
player_name = 'Karl Malone',
player_id = 'malonka01',
initial = 'm',
year = 1986:2004)
Теперь, чтобы воспроизвести ваш цикл:
bind_rows(kareem, karl) %>%
mutate(
url = pmap_chr( # iterate over multiple variables and return a character vctr
list(initial, player_id, year), # choose these variables
function(initial, player_id, year) { # and apply this function
base <- "https://www.basketball-reference.com/players"
glue('{base}/{initial}/{player_id}/gamelog/{year}') # returns the url
}),
webpage = map(url, read_html), # iterate over urls and apply read_html
temp = map(
webpage, # iterate over webpage
~ html_nodes(.x, "#pgl_basic") %>% # and apply this function
html_table())
) -> # assign to a new tibble
scrapped_data
Обратите внимание, что лямбда-нотация ~ .x
— это просто еще один способ указать функцию:
square <- function(v) {v^2}
map_dbl(1:4, ~ .x^2)
map_dbl(1:4, function(.x) .x^2)
map_dbl(1:4, square)
Спасибо @Pedro, хорошая информация и ценю более чистый подход к табличкам.
Вы можете создать URL-адреса для очистки и использовать map_df
, чтобы объединить их в один фрейм данных.
library(rvest)
library(tidyverse)
urls <- sprintf("https://www.basketball-reference.com/players/%s/%s/gamelog/%s",
players$initial, players$player_id, players$year)
result <- map_df(urls, ~.x %>%
read_html() %>%
html_nodes("#pgl_basic") %>%
html_table(), .id = 'playername') %>%
mutate(playername = players$player_name[as.numeric(playername)])
Большое спасибо, Ронак, я использовал это вместе с решением @Pedro tibble, чтобы получить то, что мне было нужно.
Теперь я замечаю, что для некоторых игроков некоторые из результирующих html_tables представляют собой смесь символов/целых чисел, а некоторые - только символы. Есть ли способ заставить очищенные данные быть всеми типами символов? У меня есть исследование map_at или map_chr, но оба они, похоже, относятся к входным данным df, а не к результирующим данным.
После html_table()
вы можете добавить %>% mutate_all(as.character)
, что заставит все столбцы иметь символьный тип.
Я попробовал это, а также некоторые версии sapply, но, похоже, у него все еще есть проблема с типами данных, когда вы зацикливаетесь на Майкле Джордане (jordami01, j, 1985: 2003). Даже с мутацией as.character DF 1985 года проходит как весь символ, а 1986 год - как смесь char/int. basketball-reference.com/players/j/jordami01/gamelog/1985
Вы можете задать новый вопрос по конкретной ссылке, с которой у вас возникла проблема.
purrr
.