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
CodePudding user response:
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