Given a dataframe:
df <- data.frame(Col1 = LETTERS[1:4], Col2 = LETTERS[23:26], Col3 = c(1:4), col4 = c(100:103))
I want to combine column with their column names. I know I can use unite
from tidyr and get the following output.
df %>% unite(NewCol, c(Col1, Col4), remove = F)
Col1 Col2 Col3 Col4 NewCol
1 A W 1 100 A_100
2 B X 2 101 B_101
3 C Y 3 102 C_102
4 D Z 4 103 D_103
But I want to have the column name next to the value of the column as follows (the separator _
is really not that important):
Col1 Col2 Col3 Col4 NewCol
1 A W 1 100 Col1_A_Col4_100
2 B X 2 101 Col1_B_Col4_101
3 C Y 3 102 Col1_C_Col4_102
4 D Z 4 103 Col1_D_Col4_103
I tried the solution posted here which does give the desired output but it creates a separate output.
imap_dfr(df %>% select(Col1, Col4), ~ paste(.y, .x, sep = "_")) %>%
unite(NewCol, sep = "_")
NewCol
<chr>
1 Col1_A_Col4_100
2 Col1_B_Col4_101
3 Col1_C_Col4_102
4 Col1_D_Col4_103
Would I simply use bind_cols()
to combine both? How do I know the sequence of the rows is preserved between the two? Is there another way that I can create NewCol
within the same dataframe similar to unite in the first case?
bind_cols()
implementation you're having trouble with?df %>% bind_cols(imap_dfr(df %>% select(Col1, Col4), ~ paste(.y, .x, sep = "_")) %>% unite(newcol, sep = "_"))
should work as expected. As for "How do I know the sequence of the rows is preserved between the two?" - I can't think of any way that 'newcol' would be in a different order to 'df' – Handspringdf %>% mutate(across(c(Col1, Col4), ~paste0(cur_column(), "_", .x))) %>% unite(newcol, c(Col1, Col4), sep = "_") %>% left_join(df)
; maybe that would suit better? – Handspringdf %>% mutate(across(c(Col1, Col4), ~paste0(cur_column(), "_", .x))) %>% unite(newcol, c(Col1, Col4), sep = "_") %>% left_join(df)
gives me the desired output with the added peace that row order is preserved. I didn't know about the existence ofcur_column()
until now. I thought the solution posted here was the way to go. – Campfire