1
votes

I have a function that returns vectors of a fixed length. It isn't this function, but consider it as a toy example:

foo = function(letter) {
    unlist(lapply(1:10, function (number) {paste(letter,number)}))
}

I have a vector of letters cols = c("A", "L", "B") and I would like to create a tibble where each column is foo(letter):

# A tibble: 10 × 3
       A     L     B
   <chr> <chr> <chr>
1    A 1   L 1   B 1
2    A 2   L 2   B 2
3    A 3   L 3   B 3
4    A 4   L 4   B 4
5    A 5   L 5   B 5
6    A 6   L 6   B 6
7    A 7   L 7   B 7
8    A 8   L 8   B 8
9    A 9   L 9   B 9
10  A 10  L 10  B 10

The above tibble was made with data_frame("A"=foo("A"), "L"=foo("L"), "B"=foo("B")), but I don't know how to do it for a vector cols of arbitrary length.

I'm certain that this is elementary and can be done without a for loop.

In a rival framework what I'm looking for can be done as

pd.DataFrame({letter: foo(letter) for letter in cols})
2
library(purrr); c("A", "L", "B") %>% set_names() %>% map_df(foo) - alistaire
@alistaire: this is exactly what I'm looking for! Please post as an answer so I can accept - user357269

2 Answers

2
votes

purrr::map_df is a version of lapply that coerces the result to a tibble. To simplify to a data.frame, the vectors have to be named, for which you can use set_names:

library(purrr)

c("A", "L", "B") %>% set_names() %>% map_df(foo)

## # A tibble: 10 × 3
##        A     L     B
##    <chr> <chr> <chr>
## 1    A 1   L 1   B 1
## 2    A 2   L 2   B 2
## 3    A 3   L 3   B 3
## 4    A 4   L 4   B 4
## 5    A 5   L 5   B 5
## 6    A 6   L 6   B 6
## 7    A 7   L 7   B 7
## 8    A 8   L 8   B 8
## 9    A 9   L 9   B 9
## 10  A 10  L 10  B 10
1
votes

We can use lapply

library(dplyr)
tbl_df(setNames(data.frame(lapply(cols, foo)), cols))
# A tibble: 10 × 3
#        A      L      B
#   <fctr> <fctr> <fctr>
#1     A 1    L 1    B 1
#2     A 2    L 2    B 2
#3     A 3    L 3    B 3
#4     A 4    L 4    B 4
#5     A 5    L 5    B 5
#6     A 6    L 6    B 6
#7     A 7    L 7    B 7
#8     A 8    L 8    B 8
#9     A 9    L 9    B 9
#10   A 10   L 10   B 10

Or another option is

setNames(tbl_df(matrix(foo(cols), ncol=3, byrow=TRUE)), cols)
# A tibble: 10 × 3
#       A     L     B
#    <chr> <chr> <chr>
#1    A 1   L 1   B 1
#2    A 2   L 2   B 2
#3    A 3   L 3   B 3
#4    A 4   L 4   B 4
#5    A 5   L 5   B 5
#6    A 6   L 6   B 6
#7    A 7   L 7   B 7
#8    A 8   L 8   B 8
#9    A 9   L 9   B 9
#10  A 10  L 10  B 10

NOTE: Only dplyr is used. No additional libraries are loaded