Reputation: 1580
I'm trying to write a function that takes a list of data.frames (somelist
) and writes them out to .csv files, each named the same as the data.frame being written (i.e., a1.csv
, a2.csv
, a3.csv
).
somelist <- list(a1 = data.frame(a = 1, b = 2, c = 3),
a2 = data.frame(d = 4, e = 5, f = 6),
a3 = data.frame(g = 7, h = 8, i = 9))
csvout <- function (y) {
z <- deparse(substitute(y))
write.table(y, file = paste0("~/somefolder/",
z,
".csv"),
sep = ",",
row.names = FALSE)
print(z)
}
sapply(somelist, csvout)
That is the closest I get, and instead, the files are named what is printed for z
:
[1] "X[[1L]]"
[1] "X[[2L]]"
[1] "X[[3L]]"
a1 a2 a3
"X[[1L]]" "X[[2L]]" "X[[3L]]"
In searching the documentation for an answer, I think I'm on the right track here in ?sapply
, but I've been unable to connect the dots:
For historical reasons, the calls created by lapply are unevaluated, and code has been written (e.g., bquote) that relies on this. This means that the recorded call is always of the form FUN(X[[i]], ...), with i replaced by the current (integer or double) index
Update
I can use a for
loop using syntax similar to C
programming...
for (i in 1:length(somelist)) {
write.table(i, file = paste0("~/somefolder/",
names(somelist)[i],
".csv"),
sep = ",",
row.names = FALSE)
}
But I'm trying to code more natively in R
and I'm aware that the apply
family, or at least using a vectorized for
loop (i.e., for (all in somelist) {
instead of for (i in 1:length(somelist)) {
) is preferable for efficiency and proper coding etiquette.
Upvotes: 1
Views: 101
Reputation: 3728
You can use apply
in similar fashion like apply(1:length,function(i){})
Upvotes: 1
Reputation: 352
This is really, really, really dirty, but I think it works as you described. Of course for more than nine data.frames it needs adjustment in the substitutes part.
csvout <- function (y, csvnames) {
write.table(y, file = paste0("test",
csvnames[as.numeric(substr(deparse(substitute(y)),4,4))],
".csv"),
sep = ",",
row.names = FALSE)
}
sapply(somelist, FUN=csvout, names(somelist))
I suppose you know that, but if you implemented a FOR-loop instead of sapply this would be much easier because you could directly reference the data.frame names with the names function.
Edit: This is the FOR-loop solution which works no matter how many data.frames you've got:
csvout <- function (y) {
for (i in 1:length(y)){
write.table(y[i], file = paste0("test",
names(y)[i],
".csv"),
sep = ",",
row.names = FALSE)
}
}
csvout(somelist)
Upvotes: 1