如何使用 r purrr:map 创建多个相同的对象(如数据框)
How to use r purrr:map to create multiple of the same object (such as data frame)
我想知道一般情况下可以在多大程度上使用 purrr 的映射函数来创建对象,尽管目前和下面的示例中我正在查看数据框。
A<-seq(1:5)
B<-seq(6:10)
C<-c("x","y","x","y","x")
dat<data.frame(A,B,C)
cols<-names(dat)
create_df<-function(x) {
x<- dat[x]
return(x)
}
A<-create_df("A")
这将创建一个名为 A 的数据框,其中包含 dat 中的 A 列。我想创建数据框 A/B/C,每个都有一列。我尝试了不同的方法来指定 .f 参数以及不同的映射函数(map、map2、map_dfc 等)。我最初的最佳猜测:
map(.x=cols,~create_df(.x))
澄清:我正在寻求帮助,因为我尝试过的所有地图规格都给出了错误。
有效代码:
map(names(dat), ~assign(.x, dat[.x], envir = .GlobalEnv))
这会创建 A/B/C 作为数据帧并打印到控制台(我不需要,但暂时不会打扰我)。
我们可以使用 base R
中的 split
得到一列 data.frame
s
的 list
lst <- split.default(dat, names(dat))
最好放在一个list
中,但如果打算在全局环境中有多个对象
list2env(lst, envir = .GlobalEnv)
使用purrr
包,我认为你的自定义函数是没有必要的。
该函数包含对数据的引用,这不是最优的(特别是如果它不存在于环境中)。
到return作为单列数据框的列表:
cols<-names(dat)
map(cols, ~dat[.x])
或者:map(names(dat), ~dat[.x])
returns:
[[1]]
# A tibble: 5 x 1
A
<int>
1 1
2 2
3 3
4 4
5 5
[[2]]
# A tibble: 5 x 1
B
<int>
1 1
2 2
3 3
4 4
5 5
[[3]]
# A tibble: 5 x 1
C
<chr>
1 x
2 y
3 x
4 y
5 x
如果您想坚持 tidyverse
原则,您可以将它们作为列表列存储在数据框中。
dfs <-
data_frame(column = cols) %>%
mutate(data = map(cols, ~dat[.x]))
# A tibble: 3 x 2
column data
<chr> <list>
1 A <tibble [5 x 1]>
2 B <tibble [5 x 1]>
3 C <tibble [5 x 1]>
您可以根据需要提取个人数据:
B <- dfs$data[[2]]
# A tibble: 5 x 1
B
<int>
1 1
2 2
3 3
4 4
5 5
按照您最初的建议,这里有一个在其中使用 purrr:map
的替代函数。我不确定这个想法有多好,但也许它有用:
create_objects_from_df <- function(dat) {
map(names(dat), ~assign(.x, dat[.x], envir = .GlobalEnv))
}
create_objects_from_df(dat)
这会在您的全局环境中创建对象,作为具有列名的单独对象。
我想知道一般情况下可以在多大程度上使用 purrr 的映射函数来创建对象,尽管目前和下面的示例中我正在查看数据框。
A<-seq(1:5)
B<-seq(6:10)
C<-c("x","y","x","y","x")
dat<data.frame(A,B,C)
cols<-names(dat)
create_df<-function(x) {
x<- dat[x]
return(x)
}
A<-create_df("A")
这将创建一个名为 A 的数据框,其中包含 dat 中的 A 列。我想创建数据框 A/B/C,每个都有一列。我尝试了不同的方法来指定 .f 参数以及不同的映射函数(map、map2、map_dfc 等)。我最初的最佳猜测:
map(.x=cols,~create_df(.x))
澄清:我正在寻求帮助,因为我尝试过的所有地图规格都给出了错误。
有效代码:
map(names(dat), ~assign(.x, dat[.x], envir = .GlobalEnv))
这会创建 A/B/C 作为数据帧并打印到控制台(我不需要,但暂时不会打扰我)。
我们可以使用 base R
中的 split
得到一列 data.frame
s
list
lst <- split.default(dat, names(dat))
最好放在一个list
中,但如果打算在全局环境中有多个对象
list2env(lst, envir = .GlobalEnv)
使用purrr
包,我认为你的自定义函数是没有必要的。
该函数包含对数据的引用,这不是最优的(特别是如果它不存在于环境中)。
到return作为单列数据框的列表:
cols<-names(dat)
map(cols, ~dat[.x])
或者:map(names(dat), ~dat[.x])
returns:
[[1]]
# A tibble: 5 x 1
A
<int>
1 1
2 2
3 3
4 4
5 5
[[2]]
# A tibble: 5 x 1
B
<int>
1 1
2 2
3 3
4 4
5 5
[[3]]
# A tibble: 5 x 1
C
<chr>
1 x
2 y
3 x
4 y
5 x
如果您想坚持 tidyverse
原则,您可以将它们作为列表列存储在数据框中。
dfs <-
data_frame(column = cols) %>%
mutate(data = map(cols, ~dat[.x]))
# A tibble: 3 x 2
column data
<chr> <list>
1 A <tibble [5 x 1]>
2 B <tibble [5 x 1]>
3 C <tibble [5 x 1]>
您可以根据需要提取个人数据:
B <- dfs$data[[2]]
# A tibble: 5 x 1
B
<int>
1 1
2 2
3 3
4 4
5 5
按照您最初的建议,这里有一个在其中使用 purrr:map
的替代函数。我不确定这个想法有多好,但也许它有用:
create_objects_from_df <- function(dat) {
map(names(dat), ~assign(.x, dat[.x], envir = .GlobalEnv))
}
create_objects_from_df(dat)
这会在您的全局环境中创建对象,作为具有列名的单独对象。