列出 knitr 环境(在 R 块中使用 list2env 时出现 R-markdown 错误)
Listing to knitr environment (R-markdown error when using list2env in R chunks)
编辑:我发现问题源于 yaml
代码。它来自将此解决方案应用于 。我相信它在 knitr
代码中创建了一个父环境,因此 list2env
产生了意想不到的行为
需要说明的是,下面的代码 运行 在 R 中是完美的。
我在 knitr
代码中使用 list2env
和 envir = .GlobalEnv
。这不起作用,因为它在 knitr
环境之外创建对象(当我在 R-markdown
中 运行 我的 R
代码时,我收到错误 ,因为创建的对象仅存在于全局环境中)。我正在尝试找到 list2env
的替代方法或告诉 list2env
列出当前 knitr
环境的方法。
R 中的准备工作
# setwd to an empty folder
setwd("C:/../testing_environment")
library(writexl)
library(readxl)
# Example data
write_xlsx(mtcars, "mt_cars.xlsx")
write_xlsx(mtcars, "mt_car_s.xlsx")
在 R-markdown 中编织的代码(link 用于安装):
---
title: thetitle
author: myinititals
output:
word_document
date: "`r Sys.Date()`"
knit: (function(inputFile, encoding) {
out_dir <- 'test';
rmarkdown::render(inputFile,
encoding=encoding,
output_file=file.path(dirname(inputFile), out_dir, 'analysis.docx')) })
```{r}
library(writexl)
library(readxl)
setwd("C:/../testing_environment")
paths <- list.files(pattern="*.xlsx")
read_all_sheets <-
function(path) sapply(excel_sheets(path), read_excel, path = path, USE.NAMES = TRUE, simplify = FALSE)
xl_list <- sapply(paths, read_all_sheets, USE.NAMES = TRUE, simplify = FALSE)
# List to environment - ISSUE
for (i in seq_along(xl_list)) {
list2env(xl_list[[i]], envir = .GlobalEnv)
}
# THIS LINE CRASHES THE CODE
names(mt_car_s)
```
错误:
我已经通过删除 names(mt_car_s)
并执行以下操作来检查会发生什么:
list2env(xl_list, envir = .GlobalEnv)
## <environment: R_GlobalEnv>
ls()
## [1] "i" "paths" "read_all_sheets"
## [4] "xl_list"
但它根本没有列出 xl_list
.
中的对象
有什么办法可以把这些文件放到环境中吗?例如写入创建的 knitr
环境的代码?如果不是,还有什么其他可能的解决方案可以防止这种行为?
编辑 2,您可以执行以下操作:
for (i in seq_along(xl_list)) {
n <- names(xl_list[[i]])
print(n)
for (j in seq_along(n)) {
assign(n[j], xl_list[[i]][[j]])
}
}
使用assign()
(默认进入当前环境)大概可以达到你想要的效果。在这里,我从列表 xl_list
中的名称中删除“.xlsx”,以便嵌套列表的第一层具有您希望成为当前环境中的对象的名称,以及 [=15= 中的名称]那些对象是sheet个名字
---
title: "Sample Document"
output:
word_document
---
```{r}
library(writexl)
library(readxl)
setwd("C:/../testing_environment")
paths <- list.files(pattern="*.xlsx")
read_all_sheets <-function(path) sapply(excel_sheets(path), read_excel, path = path, USE.NAMES = TRUE, simplify = FALSE)
xl_list <- sapply(paths, read_all_sheets, USE.NAMES = TRUE, simplify = FALSE)
# remove file extension from e.g. mt_car_s.xlsx
names(xl_list) <- gsub("\.xlsx", "", names(xl_list))
# assign each element of the list
# (itself a list of sheets/data frames)
# an object name in current environment
for (i in seq_along(xl_list)) {
n <- names(xl_list[i])
assign(n, xl_list[[i]])
}
names(mt_car_s)
names(mt_car_s$Sheet1)
```
渲染 R Markdown 文档的环境可以通过 envir
选项更改为 rmarkdown::render()
。通常,无法保证渲染环境是全局环境或其子环境——因此您不应尝试分配给 .GlobalEnv
.
相反,通过在 list2env()
调用中将 .GlobalEnv
替换为 environment()
来分配给当前环境。
编辑:我发现问题源于 yaml
代码。它来自将此解决方案应用于 knitr
代码中创建了一个父环境,因此 list2env
产生了意想不到的行为
需要说明的是,下面的代码 运行 在 R 中是完美的。
我在 knitr
代码中使用 list2env
和 envir = .GlobalEnv
。这不起作用,因为它在 knitr
环境之外创建对象(当我在 R-markdown
中 运行 我的 R
代码时,我收到错误 list2env
的替代方法或告诉 list2env
列出当前 knitr
环境的方法。
R 中的准备工作
# setwd to an empty folder
setwd("C:/../testing_environment")
library(writexl)
library(readxl)
# Example data
write_xlsx(mtcars, "mt_cars.xlsx")
write_xlsx(mtcars, "mt_car_s.xlsx")
在 R-markdown 中编织的代码(link 用于安装):
---
title: thetitle
author: myinititals
output:
word_document
date: "`r Sys.Date()`"
knit: (function(inputFile, encoding) {
out_dir <- 'test';
rmarkdown::render(inputFile,
encoding=encoding,
output_file=file.path(dirname(inputFile), out_dir, 'analysis.docx')) })
```{r}
library(writexl)
library(readxl)
setwd("C:/../testing_environment")
paths <- list.files(pattern="*.xlsx")
read_all_sheets <-
function(path) sapply(excel_sheets(path), read_excel, path = path, USE.NAMES = TRUE, simplify = FALSE)
xl_list <- sapply(paths, read_all_sheets, USE.NAMES = TRUE, simplify = FALSE)
# List to environment - ISSUE
for (i in seq_along(xl_list)) {
list2env(xl_list[[i]], envir = .GlobalEnv)
}
# THIS LINE CRASHES THE CODE
names(mt_car_s)
```
错误:
我已经通过删除 names(mt_car_s)
并执行以下操作来检查会发生什么:
list2env(xl_list, envir = .GlobalEnv)
## <environment: R_GlobalEnv>
ls()
## [1] "i" "paths" "read_all_sheets"
## [4] "xl_list"
但它根本没有列出 xl_list
.
有什么办法可以把这些文件放到环境中吗?例如写入创建的 knitr
环境的代码?如果不是,还有什么其他可能的解决方案可以防止这种行为?
编辑 2,您可以执行以下操作:
for (i in seq_along(xl_list)) {
n <- names(xl_list[[i]])
print(n)
for (j in seq_along(n)) {
assign(n[j], xl_list[[i]][[j]])
}
}
使用assign()
(默认进入当前环境)大概可以达到你想要的效果。在这里,我从列表 xl_list
中的名称中删除“.xlsx”,以便嵌套列表的第一层具有您希望成为当前环境中的对象的名称,以及 [=15= 中的名称]那些对象是sheet个名字
---
title: "Sample Document"
output:
word_document
---
```{r}
library(writexl)
library(readxl)
setwd("C:/../testing_environment")
paths <- list.files(pattern="*.xlsx")
read_all_sheets <-function(path) sapply(excel_sheets(path), read_excel, path = path, USE.NAMES = TRUE, simplify = FALSE)
xl_list <- sapply(paths, read_all_sheets, USE.NAMES = TRUE, simplify = FALSE)
# remove file extension from e.g. mt_car_s.xlsx
names(xl_list) <- gsub("\.xlsx", "", names(xl_list))
# assign each element of the list
# (itself a list of sheets/data frames)
# an object name in current environment
for (i in seq_along(xl_list)) {
n <- names(xl_list[i])
assign(n, xl_list[[i]])
}
names(mt_car_s)
names(mt_car_s$Sheet1)
```
渲染 R Markdown 文档的环境可以通过 envir
选项更改为 rmarkdown::render()
。通常,无法保证渲染环境是全局环境或其子环境——因此您不应尝试分配给 .GlobalEnv
.
相反,通过在 list2env()
调用中将 .GlobalEnv
替换为 environment()
来分配给当前环境。