I have a tibble A
such:
X1 | X2 | X3 |
---|---|---|
x1_1 | x2_1 | x3_1 |
x1_2 | x2_2 | x3_2 |
x1_3 | x2_3 | x3_3 |
x1_4 | x2_4 | x3_4 |
And a Vector Y
: (X2,X1,X3,X1...)
I want to select into a single vector B
: (x2_1,x1_2,x3_3,x1_4...)
only the values in the table A
, such the B[n]
element it is selected within the column Y[n]
.
I'd like to do this within a tidyverse pipeline, I want to avoid any for
or apply
.
I tried, after conversions of Y into integers referring to the position of the columns of A:
A %>% add_column(Y = Y) %>%
mutate(B = .[,Y])
but it does not vectorize properly.
CodePudding user response:
We may use rowwise
library(dplyr)
A %>%
add_column(Y = Y) %>%
rowwise %>%
mutate(B = cur_data()[[Y]]) %>%
ungroup
-output
# A tibble: 4 × 5
X1 X2 X3 Y B
<chr> <chr> <chr> <chr> <chr>
1 x1_1 x2_1 x3_1 X2 x2_1
2 x1_2 x2_2 x3_2 X1 x1_2
3 x1_3 x2_3 x3_3 X3 x3_3
4 x1_4 x2_4 x3_4 X1 x1_4
Or with get
A %>%
mutate(Y = Y) %>%
rowwise %>%
mutate(B = get(Y)) %>%
ungroup
Or using a vectorized solution
A %>%
mutate(B = .[cbind(row_number(), match(Y, names(.)))])
X1 X2 X3 B
1 x1_1 x2_1 x3_1 x2_1
2 x1_2 x2_2 x3_2 x1_2
3 x1_3 x2_3 x3_3 x3_3
4 x1_4 x2_4 x3_4 x1_4
Or use a vectorized row/column
indexing in base R
A$B <- A[cbind(seq_len(nrow(A)), match(Y, names(A)))]
data
A <- structure(list(X1 = c("x1_1", "x1_2", "x1_3", "x1_4"), X2 = c("x2_1",
"x2_2", "x2_3", "x2_4"), X3 = c("x3_1", "x3_2", "x3_3", "x3_4"
)), class = "data.frame", row.names = c(NA, -4L))
Y <- c("X2", "X1", "X3", "X1")
CodePudding user response:
This works too:
A %>% add_column(Y = Y) %>%
mutate(B = map2(Y, 1:n(), function(x, y){.[[x]][y]}))