我有许多单独的csv文件中的数据,我想创建一个data.frame,每个文件都有一行。下面的函数提供了用于每一行的数据。我不想更改此代码,例如包括输出向量的farmid部分。
vectorfromfile <- function(farmid) {
# Reads data from a file named farm{id}.csv, eg
# farm001.csv, and returns one named vector
# of length two with class numeric and names 'apples'
# and 'oranges' An example could be c(apples=4, oranges=6)
# The line below is a dummy for test purposes
c(apples=farmid+1000, oranges=farmid+2000)
}
然后我有一个载体,农场,例如农场&lt; - c(1,3,5)。我需要创建一个包含三列的数据框:id,apples和oranges,以及每个farmids的一行。它应该看起来像下面定义的data.frame。
> data.frame(id=c(1,3,5), apples=c(4,2,3), oranges=c(6,5,2) )
id apples oranges
1 1 4 6
2 3 2 5
3 5 3 2
我找到了几种方法,所有这些方法都非常难看,占用了很多行。但我想以最优雅的方式使用split-apply-combine方法。所以我希望我可以简单地应用(迭代)一个向量,并得到一个data.frame作为结果。像
这样的东西apply(farmids, ???? ) # farmids is a vector
这可能吗?如果没有,那么可能迭代一个具有相同值的列表?即使这是不可能的,那么最优雅的方式是什么呢。
vect2df_v1 <- function(farmids=c(1,3,5)) {
df <- data.frame(id=farmids, apples=rep(NA, length(farmids)), oranges=rep(NA, length(farmids)))
for (i in 1:length(farmids)) {
df[i, c('apples', 'oranges')] <- vectorfromfile(df[i, 'id'])
}
df
}
vect2df_v2 <- function(farmids=c(1,3,5)) {
# Obviously it could be written into one (even uglier) line
farmrow <- function(farmid) { c(farmid, vectorfromfile(farmid)) }
lst <- lapply(farmids, farmrow)
mtrx <- matrix(unlist(lst), ncol=3, byrow=T, dimnames=list(NULL,c('id', 'apples','oranges')))
data.frame(mtrx)
}
答案 0 :(得分:1)
do.call(rbind, ...)
很简单。
您可以这样写vect2df
:
vect2df <- function(vec) {
data.frame(id = vec, do.call(rbind, lapply(vec, vectorfromfile)))
}
演示:
vect2df(c(1, 3, 5))
# id apples oranges
# 1 1 1001 2001
# 2 3 1003 2003
# 3 5 1005 2005
当然,这可以通过within
直接完成(如果vectorfromfile
不是关键功能,但可以简单定义。
示例:
within(data.frame(id = c(1, 3, 5)), {
oranges <- id + 2000
apples <- id + 1000
})
# id apples oranges
# 1 1 1001 2001
# 2 3 1003 2003
# 3 5 1005 2005