Я работаю над заданием по очистке веб-страниц на следующем веб-сайте:
http://gomason.com/schedule.aspx?path=mbball
Меня просят подсчитать средний балл мужской команды (только Мейсон), когда они выиграли игру и когда они проиграли игру.
Счет каждой игры указан справа в каждой строке в формате «счет Мэйсона - счет соперника». Например, первая игра в списке имеет счет 67-65. Используя инструмент SelectorGadget, я определил селектор CSS, необходимый для очистки этой информации, а затем написал код, который очищает эту информацию. В этом векторе есть 33 элемента данных. Я использовал функцию own (), чтобы отделить оценку Мэйсона от оценки оппонента.
Я пробовал несколько вещей, но это дает мне следующую ошибку:
mens_bb <- read_html("http://gomason.com/schedule.aspx?path=mbball", na = c("NA"))
mens_scores <- mens_bb %>%
html_nodes("div.sidearm-schedule-game-result span:nth-child(3)") %>%
html_text()
as.numeric()
as.double()
mens_df <- data_frame(
date = mens_dates, time = mens_times, opponent = mens_opponents, location = mens_locations, score = mens_scores, win_loss = mens_win_loss)
mens_df$score <- as.numeric(mens_df$score)
mens_df$score <- as.double(mens_df$score)
NAs introduced by coercion
mens_df %>% separate(score, c("Mason’s score", "Opponent’s score"), sep = "\\-")
mens_average <- mean(score, na = c("NA"))
argument is not numeric or logical: returning NA
Теперь он перечислил все оценки как NA, а переменная оценка сохраняется как тип chr. Как я мог это решить?
Вот как выглядит mens_df до разделения значений очков:
Observations: 33
Variables: 6
$ date <chr> "Nov 10 (Fri)", "Nov 12 (Sun)", "Nov 16 (Thu)", "No...
$ time <chr> "7:00 p.m. ", "2:00 p.m. ", "7:00 p.m. ", "6:00 p.m...
$ opponent <chr> "Lafayette ", "Louisville", "Binghamton ", "CSUN", ...
$ location <chr> "Fairfax, Va.", "Louisville, Ky.", "Fairfax, Va. ",...
$ score <chr> "67-65", "61-72", "69-57", "78-73", "64-77", "73-79...
$ win_loss <chr> "W", "L", "W", "W", "L", "L", "W", "L", "L", "W", "...
Я представил редакции.





Вы слишком рано звоните в as.numeric(), так как в счете все еще есть тире ('-'). Вот почему вы получаете NA.
Вы можете сделать следующее: (Я создал новый фрейм данных, содержащий только оценки).
library(rvest)
mens_bb <- read_html("http://gomason.com/schedule.aspx?path=mbball", na = c("NA"))
mens_scores <- mens_bb %>%
html_nodes("div.sidearm-schedule-game-result span:nth-child(3)") %>%
html_text()
library(tidyr)
mens_df1 <- data.frame(mens_scores)
mens_df1 <- mens_df %>% separate(mens_scores, c("Mason_score", "Opponent_score"), sep = "\\-")
mens_df1$Mason_score <- as.numeric(mens_df1$Mason_score)
mens_average <- mean(mens_df1$Mason_score)
#71.84848
Вы должны сделать разделение перед преобразованием в numeric. Например, следующее даст вам желаемый результат.
mens_df <- data.frame(mens_scores)
mens_df %>% separate(mens_scores, c("Mason’s score", "Opponent’s score"), sep = "-") %>%
mutate_all(as.numeric) %>% summarise_all(mean)
# Mason’s score Opponent’s score
# 1 71.85 75.67
library(rvest)
library(tidyverse)
# read webpage/ extract only container with relevant info
bb_mason <- read_html("http://gomason.com/schedule.aspx?path=mbball") %>%
xml_find_all(".//ul[@class = 'sidearm-schedule-games-container']")
# vector with xpath to extract required info
bb_xpath <- c(opponent = ".//span[@class = 'sidearm-schedule-game-opponent-name']/a",
location = ".//div[@class = 'sidearm-schedule-game-location']/span[1]",
result = ".//div[@class = 'sidearm-schedule-game-result text-italic']/span[2]",
score = ".//div[@class = 'sidearm-schedule-game-result text-italic']/span[3]")
# sapply all xpath values, fetch information, and store in data frame tibble
bb_df <- tbl_df(
sapply(bb_xpath, function(x) {
bb_mason %>%
xml_find_all(x) %>%
xml_text(trim = T) }))
# separate scores, replace values in result column with more appropriate values,
# convert to numeric, and calculate average
bb_df %>%
separate("score", c("mason", "opp"), sep = "-") %>%
mutate(mason = as.numeric(mason),
opp = as.numeric(opp),
result = plyr::mapvalues(result, c("W,", "L,"), c("Won", "Lost"))) %>%
group_by(result) %>%
summarize(avg.score = mean(mason))
Конечный результат:
# A tibble: 2 x 2
# result avg.score
# <chr> <dbl>
# 1 Lost 65.7
# 2 Won 78.4
Большое спасибо. Это было именно то, о чем я просил, и это решило проблему.
mens_scoresникогда не кладется ни в что после соскабливания, а что есть вmens_df? Вы можете привести воспроизводимый пример?