Pedro
Pedro

Reputation: 150

Relocate based on first none zero value with dplyr

I want to order my columns based on the string name and first none zero value in each column.

assuming I have the following data:

col1_A  col2_A col1_B col2_B 
   0       0      0      0   
   0       2      0      4 
   3       12     1      1  

I need to order them in a way that columns with names including '_A' are place before '_B' and then the column with the first none zero value comes first. The expected out put will be:

col2_A  col1_A col1_B col2_B 
   0       0      0      0   
   2       0      4      0 
   12      3      1      1  

Here is the sample data for replicating.

df = data.frame('col1_A'=c(0,0,3),'col2_A'=c(0,2,12),'col1_B'=c(0,0,1),'col2_B'=c(0,4,1))

UPDATE:

Colnames are just examples, and the only the last character is important! hence I changed them to this now to avoid confusion.

Upvotes: 2

Views: 70

Answers (2)

Ronak Shah
Ronak Shah

Reputation: 389135

Here's another way using split.default -

purrr::map_dfc(split.default(df, sub('.*_', '', names(df))), function(x) {
  x[order(sapply(x, function(x) match(TRUE, x !=0)))]
})

#  col2_A col1_A col2_B col1_B
#1      0      0      0      0
#2      2      0      4      0
#3     12      3      1      1

sub keeps only the important last character in the output. We split the data accordingly.

sub('.*_', '', names(df))
#[1] "A" "A" "B" "B"

For each group (A and B) we extract the position of first non zero value (match(TRUE, x!= 0)) and use order to rearrange the dataframe. map_dfc is used to combine the list of dataframes in one combined dataframe.

Upvotes: 2

shs
shs

Reputation: 3899

library(tidyverse)
df = data.frame('col1_A'=c(0,0,3),'col2_A'=c(0,2,12),'col3_B'=c(0,0,1),'col4_B'=c(0,4,1))


df %>% 
  imap_chr(~ str_c(str_extract(.y, "\\w$"),
                   which(.x != 0)[1])) %>% 
  enframe() %>% 
  arrange(value) %>% 
  {df[.$name]}
#>   col2_A col1_A col4_B col3_B
#> 1      0      0      0      0
#> 2      2      0      4      0
#> 3     12      3      1      1

Created on 2021-09-06 by the reprex package (v2.0.1)

Upvotes: 2

Related Questions