[英]How do I make the dataframe within an R function globally accessible?
我制作了这个 R 脚本,用于使用歌词网站上的rvest
提取歌词和专辑名称。
songscrape <- function(y, a) {
url <- y
artist <- a
SongsListScrapper <- function(x) {
page <- x
songs <- page %>%
read_html() %>%
html_nodes('.listalbum-item') %>%
html_text() %>%
as.data.frame()
chart <- cbind(songs)
names(chart) <- c("Songs")
chart <- as.tibble(chart)
return(chart)
}
SongsList <- map_df(url, SongsListScrapper)
SongsList
SongsList %<>%
mutate(
Songs = as.character(Songs)
,Songs = gsub("[[:punct:]]", "", Songs)
,Songs = tolower(Songs)
,Songs = gsub(" ", "", Songs)
)
SongsList$Songs
#Scrape Lyrics
wipe_html <- function(str_html) {
gsub("<.*?>", "", str_html)
}
lyrics2 <- c()
albums2 <- c()
number <- 1
for(i in seq_along(SongsList$Songs)) {
for_url_name <- SongsList$Songs[i]
#clean name
for_url_name <- tolower(gsub("[[:punct:]]\\s", "", for_url_name))
#create url
paste_url <- paste0("https://www.azlyrics.com/lyrics/", artist,"/", for_url_name, ".html")
#open connection to url
for_html_code <-read_html(paste_url)
for_lyrics <- html_node(for_html_code, xpath = "/html/body/div[2]/div/div[2]/div[5]")
for_albums <- html_node(for_html_code, xpath = "/html/body/div[2]/div/div[2]/div[11]/div[1]/b
")
for_lyrics <- wipe_html(for_lyrics)
for_albums <- wipe_html(for_albums)
lyrics2[number] <- for_lyrics
albums2[number] <- for_albums
number <- number +1
show(paste0(for_url_name, " scrape complete!"))
Sys.sleep(10)
}
songs2 <- cbind(lyrics2, albums2) %>% as.data.frame()
songs2$albums2 <- gsub("[[:punct:]]", "", songs$albums2)
}
function songscrape
有两个参数, y
和a
,它们是 AZ 歌词上的主要艺术家页面和 url 中的艺术家姓名(例如, songscrape("https://www.azlyrics.com/i/ironwine.html", "ironwine")
)
当我运行它时,我可以看到控制台中弹出如下状态消息: "thenightdescending scrape complete!"
所以我知道 function 正确接收 arguments 但我尝试中途停止它以检查一切是否正常,当我输入时我:
View(lyrics2)
或View(songs2)
,它给了我Error: object 'songs2' not found
。
我以前没有使用过 R 函数,这是我的第一次,但我猜这是因为这些对象的 scope 仅限于 ZC1C425268E68385D1AB5074C17A94F1 内。 如何使这些在 function 之外可访问,并将 function output 这些对象作为数据帧?
我知道实现这一目标的两种方法。 首先是返回一个列表。 由于您可以将数据框保存在列表中,因此应该可以。
foo <- function(x, y){
i = x+1
k <- y+1
return(list(i, k))
}
df <- foo(1, 1)
另一种编码方式可能是:
foo <- function(x, y){
i = x+1
k <- y+1
df <- list()
df$first <- i
df$second <- k
return(df)
}
df <- foo(1, 1)
之后,您可以通过从返回的列表中提取值来创建单个数据框: df[1]
等。
第二种方法是使用<<-
运算符,它输出全局环境中的值。 但我不推荐使用这种方法。 一般来说,您希望您的 function 是一个封闭的环境,但它对于调试很有用。 始终使用return()
返回您想要的 output
foo <- function(x, y){
i = x+1
k <<- y+1
}
foo(1, 1)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.