为向量或列中的每个元素创建新的小标题
Create new tibbles for each element in a vector or column
我有一个名为 sections
的 tibble/dataframe,我想用它来创建几个新的 tibbles/dataframes。我想遍历每一行并为每一行创建一个新的 tibble。第一列提供新小标题的名称,第二和第三列提供用于另一个名为 my_text
.
的小标题的索引
sections <- structure(list(sections = c("cash_and_bank_sweep", "money_market_funds_non-sweep",
"equities"),
begin_row = c(325L, 345L, 357L),
end_row = c(345L, 357L, 384L)),
class = c("tbl_df", "tbl", "data.frame"),
row.names = c(NA, -3L))
> sections
# A tibble: 3 x 3
sections begin_row end_row
<chr> <int> <int>
1 cash_and_bank_sweep 325 345
2 money_market_funds_non-sweep 345 357
3 equities 357 384
set.seed(1)
my_text <- tibble(Strings = sample(letters, size = 1000, replace = TRUE)
> head(my_text)
# A tibble: 6 x 1
Strings
<chr>
1 y
2 d
3 g
4 a
5 b
6 w
所以我要创建的第一个标题是 cash_and_bank_sweep
。手动我可以创建如下:
cash_and_bank_sweep <- tibble(Strings = my_text$Strings[sections$begin_row[1]:sections$end_row[1]])
> head(cash_and_bank_sweep)
# A tibble: 6 x 1
Strings
<chr>
1 e
2 n
3 e
4 k
5 k
6 q
有没有什么方法可以通过循环或其他结构有效地做到这一点?
我们可以使用 pmap
创建 tibble
的 list
,如果我们需要在全局环境中作为单独的对象(不推荐),请使用 list2env
library(purrr)
lst1 <- pmap(sections[-1], ~ tibble(Strings = my_text$Strings[..1:..2]))
names(lst1) <- sections[[1]]
list2env(lst1, .GlobalEnv)
或者另一种选择是map2
lst1 <- map2(sections$begin_row, sections$end_row,
~ tibble(Strings = my_text$Strings[.x:.y]))
names(lst1) <- sections[[1]]
在base R
中,这可以用Map
来完成
lst1 <- Map(function(i, j) data.frame(Strings = my_text$Strings[i:j]),
sections$begin_row, sections$end_row)
names(lst1) <- sections[[1]]
或使用 for
循环
lst1 <- vector('list', nrow(sections))
names(lst1) <- sections[[1]]
for(i in seq_along(lst1)) {
lst1[[i]] <- data.frame(Strings = my_text$Strings[sections$begin_row[i]:sections$end_row[i]])
}
我们可以在 begin_row
和 end_row
之间创建一个序列,并以长格式获取数据,并在添加 [=15] 后使用 my_text
列执行 inner_join
=] 列。
library(tidyverse)
sections %>%
mutate(value = map2(begin_row, end_row, `:`)) %>%
unnest(value) %>%
select(-begin_row, -end_row) %>%
inner_join(my_text %>% mutate(row = row_number()), by = c('value' = 'row'))
# A tibble: 62 x 3
# sections value Strings
# <chr> <int> <chr>
# 1 cash_and_bank_sweep 325 e
# 2 cash_and_bank_sweep 326 n
# 3 cash_and_bank_sweep 327 e
# 4 cash_and_bank_sweep 328 k
# 5 cash_and_bank_sweep 329 k
# 6 cash_and_bank_sweep 330 q
# 7 cash_and_bank_sweep 331 a
# 8 cash_and_bank_sweep 332 z
# 9 cash_and_bank_sweep 333 m
#10 cash_and_bank_sweep 334 a
# … with 52 more rows
这将 return 一个包含所有必需行的单个数据框,如果您需要单独的数据框,请在最后一步后的链中添加 %>% group_split(sections)
,即 inner_join
。
我有一个名为 sections
的 tibble/dataframe,我想用它来创建几个新的 tibbles/dataframes。我想遍历每一行并为每一行创建一个新的 tibble。第一列提供新小标题的名称,第二和第三列提供用于另一个名为 my_text
.
sections <- structure(list(sections = c("cash_and_bank_sweep", "money_market_funds_non-sweep",
"equities"),
begin_row = c(325L, 345L, 357L),
end_row = c(345L, 357L, 384L)),
class = c("tbl_df", "tbl", "data.frame"),
row.names = c(NA, -3L))
> sections
# A tibble: 3 x 3
sections begin_row end_row
<chr> <int> <int>
1 cash_and_bank_sweep 325 345
2 money_market_funds_non-sweep 345 357
3 equities 357 384
set.seed(1)
my_text <- tibble(Strings = sample(letters, size = 1000, replace = TRUE)
> head(my_text)
# A tibble: 6 x 1
Strings
<chr>
1 y
2 d
3 g
4 a
5 b
6 w
所以我要创建的第一个标题是 cash_and_bank_sweep
。手动我可以创建如下:
cash_and_bank_sweep <- tibble(Strings = my_text$Strings[sections$begin_row[1]:sections$end_row[1]])
> head(cash_and_bank_sweep)
# A tibble: 6 x 1
Strings
<chr>
1 e
2 n
3 e
4 k
5 k
6 q
有没有什么方法可以通过循环或其他结构有效地做到这一点?
我们可以使用 pmap
创建 tibble
的 list
,如果我们需要在全局环境中作为单独的对象(不推荐),请使用 list2env
library(purrr)
lst1 <- pmap(sections[-1], ~ tibble(Strings = my_text$Strings[..1:..2]))
names(lst1) <- sections[[1]]
list2env(lst1, .GlobalEnv)
或者另一种选择是map2
lst1 <- map2(sections$begin_row, sections$end_row,
~ tibble(Strings = my_text$Strings[.x:.y]))
names(lst1) <- sections[[1]]
在base R
中,这可以用Map
lst1 <- Map(function(i, j) data.frame(Strings = my_text$Strings[i:j]),
sections$begin_row, sections$end_row)
names(lst1) <- sections[[1]]
或使用 for
循环
lst1 <- vector('list', nrow(sections))
names(lst1) <- sections[[1]]
for(i in seq_along(lst1)) {
lst1[[i]] <- data.frame(Strings = my_text$Strings[sections$begin_row[i]:sections$end_row[i]])
}
我们可以在 begin_row
和 end_row
之间创建一个序列,并以长格式获取数据,并在添加 [=15] 后使用 my_text
列执行 inner_join
=] 列。
library(tidyverse)
sections %>%
mutate(value = map2(begin_row, end_row, `:`)) %>%
unnest(value) %>%
select(-begin_row, -end_row) %>%
inner_join(my_text %>% mutate(row = row_number()), by = c('value' = 'row'))
# A tibble: 62 x 3
# sections value Strings
# <chr> <int> <chr>
# 1 cash_and_bank_sweep 325 e
# 2 cash_and_bank_sweep 326 n
# 3 cash_and_bank_sweep 327 e
# 4 cash_and_bank_sweep 328 k
# 5 cash_and_bank_sweep 329 k
# 6 cash_and_bank_sweep 330 q
# 7 cash_and_bank_sweep 331 a
# 8 cash_and_bank_sweep 332 z
# 9 cash_and_bank_sweep 333 m
#10 cash_and_bank_sweep 334 a
# … with 52 more rows
这将 return 一个包含所有必需行的单个数据框,如果您需要单独的数据框,请在最后一步后的链中添加 %>% group_split(sections)
,即 inner_join
。