Как написать функцию в R для загрузки файлов и сбора данных? - PullRequest
0 голосов
/ 01 апреля 2019

Есть URL-адреса, которые я сохранил, и я сохранил имена переменных в векторе.

gapminder 
if(!file.exists("./data")) {dir.create("./data")}
fileUrls <- c("https://docs.google.com/spreadsheet/pub?key=0AkBd6lyS3EmpdHo5S0J6ekhVOF9QaVhod05QSGV4T3c&output=xlsx",
         "https://docs.google.com/spreadsheet/pub?key=phAwcNAVuyj2tPLxKvvnNPA&output=xlsx",
         "https://docs.google.com/spreadsheet/pub?key=phAwcNAVuyj0XOoBL_n5tAQ&output=xlsx")
var_names <- c("GDP","life_expectancy", "population")

Я хочу заполнить функцию get_clean для загрузки и чтения в файле Excel с предоставленной ссылкиа затем поместите данные в столбец с именем переменной, указанным в var_name.

get_clean <- function(url_in, var_name){

}

Я могу сделать это в отдельном коде, но я не знаю, как записать их в функцию.

Например,

life_expect_url <- fileUrls[[2]]
download.file(life_expect_url, destfile = "./data/tmp.xlsx", mode = "wb")
life_expect <-read_excel("./data/tmp.xlsx")
# change the name of the first variable to country
names(life_expect)[[1]] <- "country"
life_expect <- life_expect %>%
    gather(key = "year", 
           value = !!var_names[[2]], 
           -country, 
           na.rm = TRUE,
           convert = TRUE)
head(life_expect, n = 5)

pop_url <- fileUrls[[3]]
download.file(pop_url, destfile = "./data/tmp.xlsx", mode = "wb")
pop <-read_excel("./data/tmp.xlsx")
# change the name of the first variable to country
names(pop)[[1]] <- "country"
pop <- pop %>%
    gather(key = "year", 
           value = !!var_names[[3]], 
           -country, 
           na.rm = TRUE,
           convert = TRUE)
head(pop, n= 5)

Я пыталсяэто

get_clean <- function(url_in, var_name){
     download.file(url_in, destfile = "./data/tmp.xlsx", mode = "wb")
     a <- read_excel("./data/tmp.xlsx")
     names(a)[[1]] <- "country"
     a <- a %>% 
       gather(key = "year",
              value = !!var_name, 
              -country, 
              na.rm = TRUE, 
              convert = TRUE) 
}
out1 <- get_clean(fileUrls[1],var_names[1])
head(out1)

Это правильно?Должен ли я использовать для цикла?

Результат должен быть таким:

## # A tibble: 6 x 3
##   country     year      GDP
##   <chr>       <dbl>     <dbl>
## 1 Algeria     1960   1280.3848       
## 2 Argentina   1960   5251.8768       
## 3 Australia   1960   9407.6851       
## 4 Austria     1960   7434.1837       
## 5 Bahamas     1960   11926.4610      

1 Ответ

0 голосов
/ 01 апреля 2019

Таким образом, файлы будут загружены как временные файлы, а конечным результатом будет список, включающий три набора данных.

fileUrls <- c("https://docs.google.com/spreadsheet/pub?key=0AkBd6lyS3EmpdHo5S0J6ekhVOF9QaVhod05QSGV4T3c&output=xlsx",
              "https://docs.google.com/spreadsheet/pub?key=phAwcNAVuyj2tPLxKvvnNPA&output=xlsx",
              "https://docs.google.com/spreadsheet/pub?key=phAwcNAVuyj0XOoBL_n5tAQ&output=xlsx")
var_names <- c("GDP","life_expectancy", "population")


get_clean <- function(fileUrl, var_name){
  tmpfile <- rep(tempfile(fileext = ".xlsx"), length(fileUrl))
  lapply(1:length(fileUrl), function(x) {
    link <- fileUrl[x]
    file <- download.file(link, tmpfile[x])
    file <- readxl::read_excel(tmpfile[x])
    names(file)[1] <- "country"
    file <- file %>%
      tidyr::gather(year, !!rlang::sym(var_names[x]), -country, 
                    na.rm = TRUE, convert = TRUE)
    file
  })
}

l <- get_clean(fileUrls, var_names)
l[[1]]

[[1]]                                                                                                                     
# A tibble: 7,988 x 3
   country     year    GDP
   <chr>      <dbl>  <dbl>
 1 Algeria     1960  1280.
 2 Argentina   1960  5252.
 3 Australia   1960  9408.
 4 Austria     1960  7434.
 5 Bahamas     1960 11926.
 6 Bangladesh  1960   255.
 7 Barbados    1960  3397.
 8 Belgium     1960  7455.
 9 Belize      1960   950.
10 Benin       1960   257.
# … with 7,978 more rows

Если вы хотите сохранить файлы в определенной папке после загрузки, вам просто нужно изменить часть, которая создает путь:

get_clean <- function(fileUrl, var_name){
  filepath <- paste0("./data", var_name, filext = ".xlsx")
  lapply(1:length(fileUrl), function(x) {
    link <- fileUrl[x]
    file <- download.file(link, filepath[x])
    file <- readxl::read_excel(filepath[x])
    names(file)[1] <- "country"
    file <- file %>%
      tidyr::gather(year, !!rlang::sym(var_names[x]), -country, 
                    na.rm = TRUE, convert = TRUE)
    file
  })
}


l <- get_clean(fileUrls, var_names)
l[[1]]

Да, вы должны сделать петлю. Но я предлагаю не использовать цикл. Вместо этого используйте лакомство. Он чистый, быстрее (если он правильно построен) и не заполняет вашу среду и ОЗУ элементами, созданными внутри цикла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...