Given some data:
library(dplyr)
library(stringr)
mydata <- expand_grid(letters = letters[1:5], numbers = 1:5)
which looks like this:
mydata
# A tibble: 25 × 2
letters numbers
<chr> <int>
1 a 1
2 a 2
3 a 3
4 a 4
5 a 5
6 b 1
7 b 2
8 b 3
9 b 4
10 b 5
# … with 15 more rows
I'd like to concatenate column 1 (letters
) and column 2 (numbers
) into a new column called name
using the column indices (i.e. without reference to the column names). I'd like to do this with an ifelse clause that specifies the order in which they are concatenated. This is what I tried:
result <- mydata %>%
mutate(name = ifelse(letters == "a", str_c(c(1,2), sep="_"), str_c(c(2,1), sep="_")))
Unfortunately, this does not produce the desired result because it simply alternates between 1 and 2:
head(result)
# A tibble: 25 × 3
letters numbers name
<chr> <int> <chr>
1 a 1 1
2 a 2 2
3 a 3 1
4 a 4 2
5 a 5 1
6 b 1 1
What I'd like to see is
# A tibble: 25 × 3
letters numbers name
<chr> <int> <chr>
1 a 1 a_1
2 a 2 a_2
3 a 3 a_3
4 a 4 a_4
5 a 5 a_5
6 b 1 1_b
7 b 2 2_b
8 b 3 3_b
9 b 4 4_b
10 b 5 5_b
11 c 1 1_c
12 c 2 2_c
...
So in short, how can I use the column indices inside str_c, instead of column names?
Update: I'd like to use pure, "vanilla" column indices like c(1,2) or something akin to this, rather than "derived" column indices that require certain inputs (e.g. str_detect or grep).
CodePudding user response:
library(tidyverse)
mydata %>%
mutate(name =
case_when(
str_detect(letters, pattern = "^a") ~ str_c(letters, numbers,
sep = "_"),
TRUE ~ str_c(numbers, letters, sep = "_")
)
)
# A tibble: 25 x 3
letters numbers name
<chr> <int> <chr>
1 a 1 a_1
2 a 2 a_2
3 a 3 a_3
4 a 4 a_4
5 a 5 a_5
6 b 1 1_b
7 b 2 2_b
8 b 3 3_b
9 b 4 4_b
10 b 5 5_b
# ... with 15 more rows
CodePudding user response:
You can use do.call
:
mydata %>%
mutate(name = ifelse(letters == "a",
do.call(str_c, c(.[1:2], sep = "_")),
do.call(str_c, c(.[2:1], sep = "_"))))
# A tibble: 25 × 3
letters numbers name
<chr> <int> <chr>
1 a 1 a_1
2 a 2 a_2
3 a 3 a_3
4 a 4 a_4
5 a 5 a_5
6 b 1 1_b
7 b 2 2_b
8 b 3 3_b
9 b 4 4_b
10 b 5 5_b
# … with 15 more rows