I have a list of dataframes with varying rows and columns. Here is an example:
> df_input_list
[[1]]
Feature Method
1 Feat1 Variant1
2 Feat2 Variant2
[[2]]
Feature2 Method2 Attribute
1 Feat3 Variant3 Attr1
2 Feat4 Variant4 Attr2
3 Feat5 Variant5 Attr3
Now I want to add strings to the entire dataframes in a list with lengt n, however, with varying strings to the respective dfs. Like this:
> df_input_list
[[1]]
Feature Method
1 String1_Feat1 String1_Variant1
2 String1_Feat2 String1_Variant2
[[2]]
Feature2 Method2 Attribute
1 String2_Feat3 String2_Variant3 String2_Attr1
2 String2_Feat4 String2_Variant4 String2_Attr2
3 String2_Feat5 String2_Variant5 String2_Attr3
I tried for
loops with paste()
, but I can not figure out the correct way.
CodePudding user response:
Using base R
Map(\(x, i) {
x[] <- paste0('String', i, as.matrix(x))
x
}
, df_input_list, seq_along(df_input_list))
CodePudding user response:
With imap
(created a mock dataset first):
library(purrr)
l <- list(head(cars), head(cars))
imap(l, \(x, y) map_dfr(x, \(z) paste0("String", y, "_", z)))
output
[[1]]
# A tibble: 6 × 2
speed dist
<chr> <chr>
1 String1_4 String1_2
2 String1_4 String1_10
3 String1_7 String1_4
4 String1_7 String1_22
5 String1_8 String1_16
6 String1_9 String1_10
[[2]]
# A tibble: 6 × 2
speed dist
<chr> <chr>
1 String2_4 String2_2
2 String2_4 String2_10
3 String2_7 String2_4
4 String2_7 String2_22
5 String2_8 String2_16
6 String2_9 String2_10
CodePudding user response:
Here's an option with purrr::map2()
so you can use both the original list as .x
and use .y
as seq_along(.x)
so you can also keep track of where you are in the list.
Note there are nested lambda functions that each use .x
as the argument which works but may be confusing at first glance.
library(tidyverse)
l <- list(
tibble(
feature = paste0("feature", 1:2),
method = paste0("variant", 1:2)
),
tibble(
feature2 = paste0("feature", 3:5),
method2 = paste0("variant", 3:5),
attribute = paste0("attr", 1:3)
)
)
l %>%
map2(.y = seq_along(.),
~mutate(.x, across(everything(), ~paste0("String", .y, "_", .x))))
#> [[1]]
#> # A tibble: 2 × 2
#> feature method
#> <chr> <chr>
#> 1 String1_feature1 String1_variant1
#> 2 String1_feature2 String1_variant2
#>
#> [[2]]
#> # A tibble: 3 × 3
#> feature2 method2 attribute
#> <chr> <chr> <chr>
#> 1 String2_feature3 String2_variant3 String2_attr1
#> 2 String2_feature4 String2_variant4 String2_attr2
#> 3 String2_feature5 String2_variant5 String2_attr3
Created on 2022-09-21 by the reprex package (v2.0.1)
CodePudding user response:
Double for
loop solution.
s <- c('String1', 'String2')
for (i in seq_along(df_input_list)) {
for (j in seq_along(df_input_list[[i]])) {
df_input_list[[i]][[j]] <- paste(s[i], df_input_list[[i]][[j]], sep='_')
}
}
df_input_list
# [[1]]
# Feature Method
# 1 String1_Feat1 String1_Variant1
# 2 String1_Feat2 String1_Variant2
#
# [[2]]
# Feature2 Method2 Attribute
# 1 String2_Feat3 String2_Variant3 String2_Attr1
# 2 String2_Feat4 String2_Variant4 String2_Attr2
# 3 String2_Feat5 String2_Variant5 String2_Attr3
Data:
df_input_list <- list(structure(list(Feature = c("Feat1", "Feat2"), Method = c("Variant1",
"Variant2")), class = "data.frame", row.names = c("1", "2")),
structure(list(Feature2 = c("Feat3", "Feat4", "Feat5"), Method2 = c("Variant3",
"Variant4", "Variant5"), Attribute = c("Attr1", "Attr2",
"Attr3")), class = "data.frame", row.names = c("1", "2",
"3")))