使用数据框名称作为模型中的列 table
Using dataframe name as a column in a model table
我很困惑为什么以下内容不起作用。我正在尝试使用数据 frame/tibble 的名称作为多模型数据框中的列,但保持 运行 以防止出现以下错误。这是一个例子:
library(tidyverse)
library(rlang)
set.seed(666)
df1 <- tibble(
x = 1:10 + rnorm(10),
y = seq(20, 38, by=2) + rnorm(10),
z = 2*x + 3*y
)
df2 <- tibble(
x = 1:10 + rnorm(10),
y = seq(20, 38, by=2) + rnorm(10),
z = 4*x + 5*y
)
results <- tibble(dataset = c('df1','df2'))
注意以下所有工作:
lm(z ~ x + y, data=df1)
lm(z ~ x + y, data=df2)
lm(z ~ x + y, data=eval(sym('df1')))
但是当我尝试以下操作时:
results <- results %>% mutate(model = lm(z ~ x + y, data = eval(sym(dataset))))
我收到错误
Error in mutate_impl(.data, dots) :
Evaluation error: Only strings can be converted to symbols.
有人能想出如何使这个工作吗?
我们可以使用map
函数,指定lm
函数如下。
library(tidyverse)
library(rlang)
results2 <- results %>%
mutate(model = map(dataset, ~lm(z ~ x + y, data = eval(sym(.)))))
results2
# # A tibble: 2 x 2
# dataset model
# <chr> <list>
# 1 df1 <S3: lm>
# 2 df2 <S3: lm>
results2$model[[1]]
# Call:
# lm(formula = z ~ x + y, data = eval(sym(.)))
#
# Coefficients:
# (Intercept) x y
# 6.741e-14 2.000e+00 3.000e+00
results2$model[[2]]
# Call:
# lm(formula = z ~ x + y, data = eval(sym(.)))
#
# Coefficients:
# (Intercept) x y
# 9.662e-14 4.000e+00 5.000e+00
我推荐一种稍微不同的路线,您可以在其中绑定所有数据并跳过 eval
和 sym
调用。这遵循 R for Data Science 的 "Many Models" 章节。
purrr::lst
创建一个数据框列表,这些变量的名称作为列表的名称,.id
参数 bind_rows
使用这些名称创建列标记来自 df1
或 df2
的数据。嵌套创建一个列 data
,它是数据框的列表列。然后您可以构建每个数据集的模型。我使用 构建了匿名函数。
结果:您有一列 model
是模型列表。
library(tidyverse)
library(rlang)
results <- lst(df1, df2) %>%
bind_rows(.id = "dataset") %>%
group_by(dataset) %>%
nest() %>%
mutate(model = map(data, ~lm(z ~ x + y, data = .)))
results$model[[1]]
#>
#> Call:
#> lm(formula = z ~ x + y, data = .)
#>
#> Coefficients:
#> (Intercept) x y
#> 6.741e-14 2.000e+00 3.000e+00
您还有一列嵌套数据。不想要的可以扔掉:
select(results, -data)
#> # A tibble: 2 x 2
#> dataset model
#> <chr> <list>
#> 1 df1 <lm>
#> 2 df2 <lm>
我很困惑为什么以下内容不起作用。我正在尝试使用数据 frame/tibble 的名称作为多模型数据框中的列,但保持 运行 以防止出现以下错误。这是一个例子:
library(tidyverse)
library(rlang)
set.seed(666)
df1 <- tibble(
x = 1:10 + rnorm(10),
y = seq(20, 38, by=2) + rnorm(10),
z = 2*x + 3*y
)
df2 <- tibble(
x = 1:10 + rnorm(10),
y = seq(20, 38, by=2) + rnorm(10),
z = 4*x + 5*y
)
results <- tibble(dataset = c('df1','df2'))
注意以下所有工作:
lm(z ~ x + y, data=df1)
lm(z ~ x + y, data=df2)
lm(z ~ x + y, data=eval(sym('df1')))
但是当我尝试以下操作时:
results <- results %>% mutate(model = lm(z ~ x + y, data = eval(sym(dataset))))
我收到错误
Error in mutate_impl(.data, dots) :
Evaluation error: Only strings can be converted to symbols.
有人能想出如何使这个工作吗?
我们可以使用map
函数,指定lm
函数如下。
library(tidyverse)
library(rlang)
results2 <- results %>%
mutate(model = map(dataset, ~lm(z ~ x + y, data = eval(sym(.)))))
results2
# # A tibble: 2 x 2
# dataset model
# <chr> <list>
# 1 df1 <S3: lm>
# 2 df2 <S3: lm>
results2$model[[1]]
# Call:
# lm(formula = z ~ x + y, data = eval(sym(.)))
#
# Coefficients:
# (Intercept) x y
# 6.741e-14 2.000e+00 3.000e+00
results2$model[[2]]
# Call:
# lm(formula = z ~ x + y, data = eval(sym(.)))
#
# Coefficients:
# (Intercept) x y
# 9.662e-14 4.000e+00 5.000e+00
我推荐一种稍微不同的路线,您可以在其中绑定所有数据并跳过 eval
和 sym
调用。这遵循 R for Data Science 的 "Many Models" 章节。
purrr::lst
创建一个数据框列表,这些变量的名称作为列表的名称,.id
参数 bind_rows
使用这些名称创建列标记来自 df1
或 df2
的数据。嵌套创建一个列 data
,它是数据框的列表列。然后您可以构建每个数据集的模型。我使用
结果:您有一列 model
是模型列表。
library(tidyverse)
library(rlang)
results <- lst(df1, df2) %>%
bind_rows(.id = "dataset") %>%
group_by(dataset) %>%
nest() %>%
mutate(model = map(data, ~lm(z ~ x + y, data = .)))
results$model[[1]]
#>
#> Call:
#> lm(formula = z ~ x + y, data = .)
#>
#> Coefficients:
#> (Intercept) x y
#> 6.741e-14 2.000e+00 3.000e+00
您还有一列嵌套数据。不想要的可以扔掉:
select(results, -data)
#> # A tibble: 2 x 2
#> dataset model
#> <chr> <list>
#> 1 df1 <lm>
#> 2 df2 <lm>