Blaze9
Blaze9

Reputation: 193

R - Dplyr - get() not applying to every column, only uses first occurrence

I have a DF that looks like this:

V1  V2  V3  V4  V5  V6
1251    V5  12  7   13  91
126 V5  17  9   75  90
912 V6  55  34  88  22

I'm trying to get the value of the column referenced in V2.

For row 1 and row 2, column V2 references V5. For row 3, V2 references V6

Using dplyr I'm trying to get the corrosponding values of the column referenced in V2.

df %>%
   mutate(V2_ref_value = get(V2)) %>%
   select(V1, V2, V2_ref_value)

This returns an odd df:

V1  V2  V2_ref_value
1251    V5  13
126 V5  75
912 V6  88

The correct values for rows 1 and 2 show, but row 3 also shows its value from column V5, and not the value from its referenced column, V6.

The correct output should be:

V1  V2  V2_ref_value
1251    V5  13
126 V5  75
912 V6  22

Does anyone know why this is happening or how I can fix this?

Upvotes: 2

Views: 38

Answers (2)

akrun
akrun

Reputation: 887531

We can use vectorized row/column subsetting in base R

df$V2_ref_value <- as.numeric(df[cbind(seq_len(nrow(df)), 
       match(df$V2, names(df)))])

-output

df
#    V1 V2 V3 V4 V5 V6 V2_ref_value
#1 1251 V5 12  7 13 91           13
#2  126 V5 17  9 75 90           75
#3  912 V6 55 34 88 22           22

data

df <- structure(list(V1 = c(1251L, 126L, 912L), V2 = c("V5", "V5", 
"V6"), V3 = c(12L, 17L, 55L), V4 = c(7L, 9L, 34L), V5 = c(13L, 
75L, 88L), V6 = c(91L, 90L, 22L)), class = "data.frame", row.names = c(NA, 
-3L))

Upvotes: 0

tmfmnk
tmfmnk

Reputation: 40141

You need to perform it row-wise:

df %>%
 rowwise() %>%
 mutate(V2_ref_value = get(V2))

     V1 V2       V3    V4    V5    V6 V2_ref_value
  <int> <chr> <int> <int> <int> <int>        <int>
1  1251 V5       12     7    13    91           13
2   126 V5       17     9    75    90           75
3   912 V6       55    34    88    22           22

Or you can also do, without the need of rowwise():

df %>%
 mutate(V2_ref_value = Reduce(`+`, across(-c(V1:V2), ~ (cur_column() == V2) * .)))

Upvotes: 2

Related Questions