如何使用 lapply 创建变量?
How would one create variables using lapply?
我的列表中有太多子数据集,因此列出每个数据集会很麻烦且非常乏味。有没有办法使用 lapply
或 purrr
来实现这一点?提前致谢。
library(dplyr)
mydata <- list(data.frame(
A = c(1, 2, 3),
B = c("Test1", "Test2", "Test3")),
data.frame(
A = c(10, 21, 30),
B = c("Test10", "Test24", "Test32")))
names(mydata) <- c("dat1", "dat2")
mydata$dat1 <- mydata$dat1 %>%
mutate(id = "dat1")
mydata$dat2 <- mydata$dat2 %>%
mutate(id = "dat2")
基础 R 解决方案可以使用 Map
,即
Map(function(x, y)transform(x, id = y), mydata, paste0('dat', seq(length(mydata))))
这应该可以解决问题:
listNames <- c("dat1", "dat2")
names(mydata) <- listNames
mydata <- lapply(
listNames,
function(x) {
mydata[[x]] %>% mutate(id = x)
}
)
names(mydata) <- listNames
mydata
$dat1
A B id
1 1 Test1 dat1
2 2 Test2 dat1
3 3 Test3 dat1
$dat2
A B id
1 10 Test10 dat2
2 21 Test24 dat2
3 30 Test32 dat2
lapply
、
的另一种方法
invisible(lapply(seq(mydata), function(x) mydata[[x]]['id'] <<-names(mydata[x])))
mydata
给予,
$dat1
A B id
1 1 Test1 dat1
2 2 Test2 dat1
3 3 Test3 dat1
$dat2
A B id
1 10 Test10 dat2
2 21 Test24 dat2
3 30 Test32 dat2
这是 purrr::imap
的完美案例。
如果 mylist
已经命名:
library(dplyr)
library(purrr)
# if `mydata` is already named:
imap(mydata, ~ mutate(.x, id = .y))
#> $dat1
#> A B id
#> 1 1 Test1 dat1
#> 2 2 Test2 dat1
#> 3 3 Test3 dat1
#>
#> $dat2
#> A B id
#> 1 10 Test10 dat2
#> 2 21 Test24 dat2
#> 3 30 Test32 dat2
如果 mydata
尚未命名,我们也可以使用 imap
:
library(dplyr)
library(purrr)
mydata <- list(data.frame(
A = c(1, 2, 3),
B = c("Test1", "Test2", "Test3")),
data.frame(
A = c(10, 21, 30),
B = c("Test10", "Test24", "Test32")))
imap(mydata, ~ mutate(.x, id = glue::glue("dat{.y}")))
#> [[1]]
#> A B id
#> 1 1 Test1 dat1
#> 2 2 Test2 dat1
#> 3 3 Test3 dat1
#>
#> [[2]]
#> A B id
#> 1 10 Test10 dat2
#> 2 21 Test24 dat2
#> 3 30 Test32 dat2
由 reprex package (v2.0.1)
于 2022-01-18 创建
这听起来像是使用 imap
的好时机,它对处理列表名称很有用:
purrr::imap(mydata, ~mutate(.x, id = .y))
# $dat1
# A B id
# 1 1 Test1 dat1
# 2 2 Test2 dat1
# 3 3 Test3 dat1
# $dat2
# A B id
# 1 10 Test10 dat2
# 2 21 Test24 dat2
# 3 30 Test32 dat2
我的列表中有太多子数据集,因此列出每个数据集会很麻烦且非常乏味。有没有办法使用 lapply
或 purrr
来实现这一点?提前致谢。
library(dplyr)
mydata <- list(data.frame(
A = c(1, 2, 3),
B = c("Test1", "Test2", "Test3")),
data.frame(
A = c(10, 21, 30),
B = c("Test10", "Test24", "Test32")))
names(mydata) <- c("dat1", "dat2")
mydata$dat1 <- mydata$dat1 %>%
mutate(id = "dat1")
mydata$dat2 <- mydata$dat2 %>%
mutate(id = "dat2")
基础 R 解决方案可以使用 Map
,即
Map(function(x, y)transform(x, id = y), mydata, paste0('dat', seq(length(mydata))))
这应该可以解决问题:
listNames <- c("dat1", "dat2")
names(mydata) <- listNames
mydata <- lapply(
listNames,
function(x) {
mydata[[x]] %>% mutate(id = x)
}
)
names(mydata) <- listNames
mydata
$dat1
A B id
1 1 Test1 dat1
2 2 Test2 dat1
3 3 Test3 dat1
$dat2
A B id
1 10 Test10 dat2
2 21 Test24 dat2
3 30 Test32 dat2
lapply
、
invisible(lapply(seq(mydata), function(x) mydata[[x]]['id'] <<-names(mydata[x])))
mydata
给予,
$dat1
A B id
1 1 Test1 dat1
2 2 Test2 dat1
3 3 Test3 dat1
$dat2
A B id
1 10 Test10 dat2
2 21 Test24 dat2
3 30 Test32 dat2
这是 purrr::imap
的完美案例。
如果 mylist
已经命名:
library(dplyr)
library(purrr)
# if `mydata` is already named:
imap(mydata, ~ mutate(.x, id = .y))
#> $dat1
#> A B id
#> 1 1 Test1 dat1
#> 2 2 Test2 dat1
#> 3 3 Test3 dat1
#>
#> $dat2
#> A B id
#> 1 10 Test10 dat2
#> 2 21 Test24 dat2
#> 3 30 Test32 dat2
如果 mydata
尚未命名,我们也可以使用 imap
:
library(dplyr)
library(purrr)
mydata <- list(data.frame(
A = c(1, 2, 3),
B = c("Test1", "Test2", "Test3")),
data.frame(
A = c(10, 21, 30),
B = c("Test10", "Test24", "Test32")))
imap(mydata, ~ mutate(.x, id = glue::glue("dat{.y}")))
#> [[1]]
#> A B id
#> 1 1 Test1 dat1
#> 2 2 Test2 dat1
#> 3 3 Test3 dat1
#>
#> [[2]]
#> A B id
#> 1 10 Test10 dat2
#> 2 21 Test24 dat2
#> 3 30 Test32 dat2
由 reprex package (v2.0.1)
于 2022-01-18 创建这听起来像是使用 imap
的好时机,它对处理列表名称很有用:
purrr::imap(mydata, ~mutate(.x, id = .y))
# $dat1
# A B id
# 1 1 Test1 dat1
# 2 2 Test2 dat1
# 3 3 Test3 dat1
# $dat2
# A B id
# 1 10 Test10 dat2
# 2 21 Test24 dat2
# 3 30 Test32 dat2