我正在寻找列表中的数据框。尽管我目前做出了最大的努力,但我得到的'下标数量不正确'和类似的错误。这是我的代码:
folder = 'C:/Path to csv files-071813/'
symbs = c('SPX', 'XLF', 'XLY', 'XLV', 'XLI', 'IYZ', 'XLP', 'XLE', 'XLK', 'XLB', 'XLU', 'SHV')
importData = vector('list', length(symbs))
names(importData) = symbs
for (sIdx in 1:length(symbs)){
#Import the data for each symbol into the list.
importData[sIdx] = read.csv(paste(folder, symbs[sIdx], '.csv', sep = ''), header = TRUE)
}
每个csv文件有数千行和7列。 我假设我上面的内容是从每个csv文件返回一个数据框到我的列表中。 我想进入:
importData[[1]][, 1]
使用列表中第一个数据框的第一列。我接近了吗?尽管我都在寻找,但我无法找到解决方案。非常感谢...
答案 0 :(得分:4)
apply
系列函数将成为你的朋友,特别是lapply
,这是一个函数,给定一个列表和一个函数,将函数应用于该列表的每个元素并返回结果作为新列表的元素。
folder = 'C:/Path to csv files-071813/'
symbs = c('SPX', 'XLF', 'XLY', 'XLV', 'XLI', 'IYZ', 'XLP', 'XLE', 'XLK', 'XLB', 'XLU', 'SHV')
filenames = paste0(folder,symbs,'.csv')
listOfDataframes=lapply(filenames,read.table,header=T)
现在,如果您想要所有数据框中的第二列,您可以执行类似
的操作listOfFirstCols=lapply(listOfDataframes,"[",,2)
或者更明确地
listOfFirstCols=lapply(listOfDataframes,function(x)x[,1])
答案 1 :(得分:1)
是的,你很亲密。你需要
importData[[sIdx]] <- read.csv(....)
(即[[
)因为你想在sIdx
组件中分配内的数据框。单括号[
需要分配一个列表。
importData[[1]]
返回importData[1]
内的对象。这是一个细微的差别,后者返回包含第一个组件的列表,而前者返回该列表中的对象。
由于importData[[sIdx]]
是一个数据框,您可以像对待任何其他数据框一样对其进行索引。将importData[[sIdx]]
视为数据框df
可能会有所帮助,然后添加您通常用于索引第一列的内容,即df[, 1]
(或df[[1]]
),然后替换回真实对象而不是df
df[, 1]
importData[[sIdx]][, 1] ## substitute back in the real object for `df`
如果您想依次提取每个第一列,那么
lapply(importData, `[`, , 1) ## matches df[, 1]
或
lapply(importData, `[[`, 1) ## matches df[[1]]
会将它们作为列表返回,使用sapply()
而不是lapply()
的版本将结果简化为数组。
请注意,在第一个例子中
lapply(importData, `[`, , 1)
空参数(, , 1
)很重要,因为它引用df[ , 1]
中的空参数,即逗号之前的位。因此,在[[
调用中使用lapply()
的第二个选项可能不太容易出错,为什么我之前提到它。
答案 2 :(得分:0)
> myfunc<-function(a,b){ ###a is numeric (vector of) symbol indices to
> include,b is (vector of) column indices to include
> if (length(a)>0){
> importalldata<-read.csv(paste(folder, symbs[a[1]], '.csv', sep = ''), header = TRUE)[b]
> if (length(a)>1){
> for(i in 2:length(d)){
> importalldata<-rbind(importalldata,read.csv(paste(folder, symbs[a[i]], '.csv', sep = ''), header = TRUE)[b])
> }
> }else{print('Must select at least one symbol')}
> return(importalldata)
> }
为一个符号加载数据,执行:
importalldata<-myfunc(1,1)
表示多个符号:
importalldata<-myfunc(c(1,3,4),1)
表示多列:
importalldata<-myfunc(c(1,3,4),1:3)
我认为这就是你想要的?或者您是否尝试将每个文件的所有列1都放入1个数据帧中?如果您包含可重现的数据,您将得到更好的答案。
也就是说,成千上万的行并不多,你最好将你的数据组合('堆叠')成1 csv作为因子,然后使用subset / data.table包来选择你想要的数据。看看
?stack