如何将多文件.xlsx数据导入到没有级别的单个R数据帧中?

时间:2017-03-12 07:00:11

标签: r excel import xlsx readxl

我正在尝试从一些免费的纳斯达克100个Twitter数据集中提取每个公司的数据here。一旦构建和策划,最终目标是使用数据框运行一些建模实验。我的目标基本数据框架形式是:

ATVI  49.02   0.44   0.91   7193022   .3 
ADBE  119.91  0.31   0.26   1984225   .1 
AKAM  64.2    0.65   1.02   1336622   .1 
ALXN  126.55  0.86   0.67   2182253   .2
GOOG  838.68  3.31   0.4    1261517  1.0 
AMZN  853     2.5    0.29   2048187  1.0

对于每个公司,有六个.xlsx文件(解压缩到不同的目录中),每个excel文件里面有多个工作表。目前,我只想从每个公司的六个excels电子表格中的每一个中提取第一个工作表。所有这些工作表都有两列,行数不同,数据标签位于不同的行上,例如文件1,公司1:

Keyword             $AAPL -
Total tweets        166631
Total audience      221363515
Contributors        42738
Original tweets     91614
Replies             4964
RTs                 70053
Images and links    43361

文件2,公司1:

Keyword                        $AAPL -
Total audience                 221363515
Contributors                   42738
Total tweets                   166631
Total potential impressions    1.250.920.501
Measured data from             2016-04-02 18:06
Measured data to               2016-06-15 12:23
Tweets per contributor         3,90
Impressions / Audience         5,65
Measured time in seconds       6373058
Measured time in minutes       106218
Measured time in hours         1770
Measured time in days          74
Tweets per second              0.026146161
Tweets per minute              1.568769655
Tweets per hour                94.1261793
Tweets per day                 2259.028303

我正在尝试按照post中的建议实施readxl,然后将每个公司的数据放入数据框的一行[下方]。现在,我将第一个路径设置为我的目录,然后运行代码,然后设置第二个路径并再次运行它以添加新行(我知道这不是最佳的,见下文)。

library(readxl)

#create empty dataframe to assemble all the rows
cdf <- data.frame()

#setwd('...\\NASDAQ_100\\aal_2016_06_15_12_01_41')
#setwd('...\\NASDAQ_100\\aapl_2016_06_15_14_30_09')

#constructing list of all .xlsx files in current directory
file.list <- list.files(pattern='*.xlsx')

#using read_excel function to read each file in list and put in a dataframe of lists 
df.list <- lapply(file.list, read_excel)

#converting the dataframe of lists to a 77x2 dataframe
df <- as.data.frame(do.call(rbind, df.list),stringsAsFactors=FALSE)

#transposing the dataframe to prepare to stack multiple companies data in single dataframe
df <- t(df)

#making sure that the dataframe entry values are numeric
df <- transform(df,as.numeric)

#appending the 2nd row with the actual data into the dataframe that will have all companies' data
cdf <- rbind(cdf,df[2,])

示例输出:

> cdf[,1:8]
            X1        X2    X3    X4   X5    X6    X7        X8
$AAL      6507  14432722  1645  5211  459   837   938  14432722
$AAPL - 166631 221363515 42738 91614 4964 70053 43361 221363515

经过检查,我发现我的专栏中有一些级别,我从各种其他帖子中收集的是因为我导入数据的方式,这就是为什么我尝试将stringsAsFactors=FALSE添加到{{1但是,显然这不是解决方案:

as.data.frame

根据文档,这不是> cdf[,2] $AAL $AAPL - 14432722 221363515 Levels: 14432722 Total audience 221363515 的论据。有没有办法继续使用它,但避免这些水平?

一旦我对它进行了整理,我希望在基本的for循环中得到它来遍历所有解压缩的子目录:

read_excel

但这会产生dir.list <- list.dirs(recursive = F) for (subdir in dir.list) { file.list <- list.files(pattern='*.xlsx') df.list <- lapply(file.list, read_excel) df <- as.data.frame(do.call(rbind, df.list),stringsAsFactors=FALSE) df <- t(df) df <- transform(df,as.numeric) cdf <- rbind(cdf,df[2,]) } ?我知道没有一个代码优雅或紧凑(并且rbind在for循环中是不明智的),但它是我能够拼凑在一起的东西。我非常容易接受样式修正和替代方法,但如果在这里描述的整体问题/解决方案中解释它们的上下文(即:不仅仅是“使用包xyz”或“读取ldply()),我们将非常感激。的文件“)。

谢谢,

2 个答案:

答案 0 :(得分:1)

我想你的df.list包含带有因子而不是字符串的data.frames,这可能是导致后续rbind出现问题的原因。你能尝试一下:

df.list <- lapply(file.list, function(x) {
             as.data.frame(read_excel(x), stringsAsFactors=FALSE)
           })

这样,df.list中的data.frames不应包含因子。

答案 1 :(得分:1)

.xlsx文件中的数据似乎存储在密钥(第1列)和值(第2列)结构中。我会使用readxldata.table来读取数据,并最初将其存储为长键/值格式(第三列表示公司)。然后我将(dcast)长格式转换为宽格式,以便每个键获得它自己的列:

library(readxl)
library(data.table)

# Get list of files
file.list <- list.files(path = ".", pattern = "*.xlsx")

# Iterate over files
dt_list <- lapply(seq_along(file.list), function(x) {
  # Read sheet 1 as data.table
  dt <- data.table(read_excel(file.list[x], sheet = 1))
  # Get company based on name of second column
  company <- gsub(colnames(dt)[2], pattern = "[^A-Z]*", replacement = "")
  # Set company and file_name (optional for debugging)
  dt[, ":="(company = company, file_name = file.list[x])]
  setnames(dt, c("key", "value", "company", "file_name"))
  dt
})
dt <- rbindlist(dt_list, use.names = TRUE)

# Get rid of file_name and remove duplicates
dt[, file_name := NULL]
dt <- unique(dt)

# Optional filtering on key
# dt <- dt[key %in% c("Total tweets", "Total audience")]

# Use dcast to make wide format table with one row per company
dt_wide <- dcast(dt, formula = company~key)

dt_wide的内容(使用AAPL和ATVI):

    company Average contributor followers Average contributor following Contributor followers median ...
 1:    AAPL                       5197,58                        832,06                       141,00 ...
 2:    ATVI                       9769,01                       1389,17                       562,00 ...

您可以使用dt_wide

data.frame转换为标准df <- as.data.frame(dt_wide)