1

I have this dataframe (but very big that includes many rows in the name variable that hold the values yes and no)

df = data.frame(name = c('a','b','c',NA,NA,'yes','no',NA,NA,'f','g','h'),
                Freq = c(10,20,70,NA,NA,40,60,NA,NA,80,10,10) )


# output

    name Freq
1     a   10
2     b   20
3     c   70
4  <NA>   NA
5  <NA>   NA
6   yes   40
7    no   60
8  <NA>   NA
9  <NA>   NA
10    f   80
11    g   10
12    h   10

For every two consective rows that include yes and no in the name column, I wish them to be flipped to become as follows :

# output

    name Freq
1     a   10
2     b   20
3     c   70
4  <NA>   NA
5  <NA>   NA
6    no   60
7   yes   40
8  <NA>   NA
9  <NA>   NA
10    f   80
11    g   10
12    h   10

Appreciate the help

Anas116
  • 797
  • 2
  • 9
  • what if more than 2 consecutive rows have yes, no in name ? how would they be flipped? lets say rows 1,2,3,4 are Y,N,Y,N: 1 and 2 flip ; 1 and 3 dont flip; 3 and 4 flip: result would be 2N,1Y,4N,3Y ? – user12256545 Nov 26 '22 at 10:35

1 Answers1

1

One approach is as follows:

  • Check which rows contain adjacent yes/no vales
  • Create an index vector which swaps the numbers of these rows
  • Use this vector to re-order the data
df = data.frame(name = c('a','b','c',NA,NA,'yes','no',NA,NA,'f','g','h','no','yes'),
                Freq = c(10,20,70,NA,NA,40,60,NA,NA,80,10,10,20,20) )

# first find the adjacent rows containing 'yes' and 'no'
# i.e. row contains yes/no & next row contains yes/no & they are not the same
rows <- which(
        df$name %in% c('yes','no') &
        c(df[-1, 'name'],NA) %in% c('yes','no') & 
        df$name != c(df[-1,'name'],NA)
)

# next, swap the row with the next row for each of these by creating an index 
#     variable with these numbers swapped
index <- 1:nrow(df)
index[rows]<-rows+1
index[rows+1] <- rows
df <- df[index,]

print(df)
   name Freq
1     a   10
2     b   20
3     c   70
4  <NA>   NA
5  <NA>   NA
7    no   60
6   yes   40
8  <NA>   NA
9  <NA>   NA
10    f   80
11    g   10
12    h   10
shaun_m
  • 1,213
  • 3
  • 13