如何将多文件 .xlsx 数据导入没有级别的单个 R 数据帧?
How to import multi-file .xlsx data into single R dataframe without levels?
我正在尝试从一些可用的免费纳斯达克 100 推特数据集中提取每家公司的数据 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 文件里面有多个工作表。目前,我只是尝试从每个公司的六个 excel 电子表格中提取第一个工作表。所有这些工作表都有两列,行数不同,数据标签位于不同的行上,例如文件 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
我正尝试按照此 中的建议实施 readxl
,然后将每个公司的数据放入数据框的一行中 [如下]。现在,我将第一个路径设置为我的目录,然后 运行ning 代码,然后设置第二个路径并再次 运行ning 它以添加新行(我知道这不是最佳,见下文)。
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
添加到 as.data.frame
,但显然这不是解决方案:
> cdf[,2]
$AAL $AAPL -
14432722 221363515
Levels: 14432722 Total audience 221363515
根据文档,这不是 read_excel
的论点。有没有办法仍然使用它,但避免这些级别?
一旦我解决了这个问题,我希望在一个基本的 for 循环中得到它来遍历所有解压缩的子目录:
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,])
}
但这会产生 > cdf data frame with 0 columns and 0 rows
?我知道 none 的代码是优雅的或紧凑的(& rbind 在 for 循环中是不明智的),但这是我能够拼凑起来的。我非常乐于接受样式更正和替代方法,但如果它们的上下文在此处描述的整体 problem/solution 中得到解释(即:不只是 "use package xyz" 或 "read ldply()'s documentation").
谢谢,
我想您的 df.list 包含带有因子而不是字符串的 data.frames,这可能是导致后续 rbind 出现问题的原因。你能试试吗:
df.list <- lapply(file.list, function(x) {
as.data.frame(read_excel(x), stringsAsFactors=FALSE)
})
这样 df.list 中的 data.frames 不应包含因子。
.xlsx
文件中的数据似乎存储在键(第 1 列)和值(第 2 列)结构中。我会使用 readxl
和 data.table
来读取数据并最初将其存储为长 key/value 格式(第三列表示公司)。然后我将 (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 ...
您可以使用 df <- as.data.frame(dt_wide)
将 dt_wide
转换为标准 data.frame
我正在尝试从一些可用的免费纳斯达克 100 推特数据集中提取每家公司的数据 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 文件里面有多个工作表。目前,我只是尝试从每个公司的六个 excel 电子表格中提取第一个工作表。所有这些工作表都有两列,行数不同,数据标签位于不同的行上,例如文件 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
我正尝试按照此 readxl
,然后将每个公司的数据放入数据框的一行中 [如下]。现在,我将第一个路径设置为我的目录,然后 运行ning 代码,然后设置第二个路径并再次 运行ning 它以添加新行(我知道这不是最佳,见下文)。
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
添加到 as.data.frame
,但显然这不是解决方案:
> cdf[,2]
$AAL $AAPL -
14432722 221363515
Levels: 14432722 Total audience 221363515
根据文档,这不是 read_excel
的论点。有没有办法仍然使用它,但避免这些级别?
一旦我解决了这个问题,我希望在一个基本的 for 循环中得到它来遍历所有解压缩的子目录:
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,])
}
但这会产生 > cdf data frame with 0 columns and 0 rows
?我知道 none 的代码是优雅的或紧凑的(& rbind 在 for 循环中是不明智的),但这是我能够拼凑起来的。我非常乐于接受样式更正和替代方法,但如果它们的上下文在此处描述的整体 problem/solution 中得到解释(即:不只是 "use package xyz" 或 "read ldply()'s documentation").
谢谢,
我想您的 df.list 包含带有因子而不是字符串的 data.frames,这可能是导致后续 rbind 出现问题的原因。你能试试吗:
df.list <- lapply(file.list, function(x) {
as.data.frame(read_excel(x), stringsAsFactors=FALSE)
})
这样 df.list 中的 data.frames 不应包含因子。
.xlsx
文件中的数据似乎存储在键(第 1 列)和值(第 2 列)结构中。我会使用 readxl
和 data.table
来读取数据并最初将其存储为长 key/value 格式(第三列表示公司)。然后我将 (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 ...
您可以使用 df <- as.data.frame(dt_wide)
dt_wide
转换为标准 data.frame