我正在尝试从网站上将很多csv文件读入R中。 Threa是每日(仅限工作日)文件的多年。所有文件都具有相同的数据结构。我可以使用以下逻辑成功读取一个文件:
# enter user credentials
user <- "JohnDoe"
password <- "SecretPassword"
credentials <- paste(user,":",password,"@",sep="")
web.site <- "downloads.theice.com/Settlement_Reports_CSV/Power/"
# construct path to data
path <- paste("https://", credentials, web.site, sep="")
# read data for 4/10/2013
file <- "icecleared_power_2013_04_10"
fname <- paste(path,file,".dat",sep="")
df <- read.csv(fname,header=TRUE, sep="|",as.is=TRUE)
但是,我正在寻找有关如何一次读取目录中所有文件的提示。我想我可以生成一个日期序列,在循环中构造上面的文件名,并使用rbind附加每个文件,但这似乎很麻烦。此外,在尝试阅读没有文件的周末和假日时会出现问题。
下面的插入内容显示了Web浏览器中文件列表的内容:
... ... ...
有没有办法扫描路径(从上面)以获取目录中首先满足certin crieteia的所有文件名列表(即以“icecleared_power_”开头,因为该位置还有一些文件有一个不同的起始名称,我不想读入)然后循环read.csv通过该列表并使用rbind追加?
非常感谢任何指导?
答案 0 :(得分:5)
我首先尝试抓取相关数据文件的链接,并使用生成的信息构建包含用户登录等的完整下载路径。正如其他人所建议的那样,lapply
可以方便批量下载。
这是一种提取网址的简便方法。显然,修改示例以适合您的实际情况。
在这里,我们将使用XML
包来识别Amelia软件包(http://cran.r-project.org/src/contrib/Archive/Amelia/)的CRAN档案中的所有可用链接。
> library(XML)
> url <- "http://cran.r-project.org/src/contrib/Archive/Amelia/"
> doc <- htmlParse(url)
> links <- xpathSApply(doc, "//a/@href")
> free(doc)
> links
href href href
"?C=N;O=D" "?C=M;O=A" "?C=S;O=A"
href href href
"?C=D;O=A" "/src/contrib/Archive/" "Amelia_1.1-23.tar.gz"
href href href
"Amelia_1.1-29.tar.gz" "Amelia_1.1-30.tar.gz" "Amelia_1.1-32.tar.gz"
href href href
"Amelia_1.1-33.tar.gz" "Amelia_1.2-0.tar.gz" "Amelia_1.2-1.tar.gz"
href href href
"Amelia_1.2-2.tar.gz" "Amelia_1.2-9.tar.gz" "Amelia_1.2-12.tar.gz"
href href href
"Amelia_1.2-13.tar.gz" "Amelia_1.2-14.tar.gz" "Amelia_1.2-15.tar.gz"
href href href
"Amelia_1.2-16.tar.gz" "Amelia_1.2-17.tar.gz" "Amelia_1.2-18.tar.gz"
href href href
"Amelia_1.5-4.tar.gz" "Amelia_1.5-5.tar.gz" "Amelia_1.6.1.tar.gz"
href href href
"Amelia_1.6.3.tar.gz" "Amelia_1.6.4.tar.gz" "Amelia_1.7.tar.gz"
为了演示,想象一下,最终,我们只想要1.2版本软件包的链接。
> wanted <- links[grepl("Amelia_1\\.2.*", links)]
> wanted
href href href
"Amelia_1.2-0.tar.gz" "Amelia_1.2-1.tar.gz" "Amelia_1.2-2.tar.gz"
href href href
"Amelia_1.2-9.tar.gz" "Amelia_1.2-12.tar.gz" "Amelia_1.2-13.tar.gz"
href href href
"Amelia_1.2-14.tar.gz" "Amelia_1.2-15.tar.gz" "Amelia_1.2-16.tar.gz"
href href
"Amelia_1.2-17.tar.gz" "Amelia_1.2-18.tar.gz"
您现在可以按如下方式使用该向量:
wanted <- links[grepl("Amelia_1\\.2.*", links)]
GetMe <- paste(url, wanted, sep = "")
lapply(seq_along(GetMe),
function(x) download.file(GetMe[x], wanted[x], mode = "wb"))
上面示例中的最后一步将指定文件下载到当前工作目录(使用getwd()
验证其位置)。相反,如果你确定read.csv
对数据起作用,你也可以尝试修改你的匿名函数来直接读取文件:
lapply(seq_along(GetMe),
function(x) read.csv(GetMe[x], header = TRUE, sep = "|", as.is = TRUE))
但是,我认为更安全的方法可能是首先将所有文件下载到单个目录中,然后使用read.delim
或read.csv
或其他任何可读取的内容数据类似于@Andreas建议的数据。我说更安全因为它可以让你在没有完全下载的情况下提供更大的灵活性等等。在这种情况下,您只需要下载未完全下载的文件,而不必重新下载所有内容。
答案 1 :(得分:1)
您可以尝试使用命令“download.file”。
### set up the path and destination
path <- "url where file is located"
dest <- "where on your hard disk you want the file saved"
### Ask R to try really hard to download your ".csv"
try(download.file(path, dest))
这样做的诀窍是弄清楚文件之间“url”或“path”如何系统地改变。通常,网页的构建使得“网址”是系统的。在这种情况下,您可以创建url的向量或数据框,以在apply函数内部进行迭代。
所有这些都可以夹在“lapply”中。 “数据”对象就是我们迭代的任何东西。它可以是URL的矢量或年和月观察的数据框,然后可以用于在“lapply”函数中创建URL。
### "dl" will apply a function to every element in our vector "data"
# It will also help keep track of files which have no download data
dl <- lapply(data, function(x) {
path <- 'url'
dest <- './data_intermediate/...'
try(download.file(path, dest))
})
### Assign element names to your list "dl"
names(dl) <- unique(data$name)
index <- sapply(dl, is.null)
### Figure out which downloads returned nothing
no.download <- names(dl)[index]
然后您可以使用“list.files()”将所有数据合并在一起,假设它们属于一个data.frame
### Create a list of files you want to merge together
files <- list.files()
### Create a list of data.frames by reading each file into memory
data <- lapply(files, read.csv)
### Stack data together
data <- do.call(rbind, data)
有时,您会注意到文件在下载后已损坏。在这种情况下,请注意download.file()命令中包含的选项“mode”。如果文件以二进制格式存储,则可以设置mode =“w”或mode =“wb”。
答案 2 :(得分:1)
@MikeTP,如果所有报告都以“icecleared_power_”开头,而日期是商业日期,则“timeDate”软件包提供了一种创建业务日期向量的简便方法,如下所示:
require(timeDate)
tSeq <- timeSequence("2012-01-01","2012-12-31") # vector of days
tBiz <- tSeq[isBizday(tSeq)] # vector of business days
和
paste0("icecleared_power_",as.character.Date(tBiz))
为您提供连接的文件名。
如果网站遵循关于文件命名的不同逻辑,我们需要更多信息,如Ananda Mahto所观察到的那样。
请记住,当您使用timeDate创建日期向量时,您可以比我的简单示例更复杂。您可以考虑假期时间表,证券交易所日期等。