Here a solution with Base R only, using TarJae's construction of the data, for a dataframe x:
# Create a vector with the row indeces that contain the target string:
target <- grep( 'red', x[ , 2 ] )
# Put these rows away in a separate data.frame:
stash <- x[ target, ]
# Set the value of the original rows to `0`
x[ target, 3 ] <- 0
# Set the values in the separated rows to their negative value
stash[ , 3 ] <- stash[ , 3 ] * -1
# Modify `names` as desired:
for( i in 1 : length( stash[ , 1 ] ) )
stash[ i, 1 ] <- paste( stash[ i, 1 ], i, sep = "" )
# Insert the modified data (supposes that the dataframe is expected
# to be sorted on the first column):
x <- rbind( x, stash )
x <- x[ order(x[ 1 ] ), ]
That gives you
> x
names variables value
1 colour c(red, blue) 0
2 colour c(yellow, blue) 32
3 colour c(green, red, pink) 0
4 colour c(pink, purple) 14
11 colour1 c(red, blue) -10
31 colour2 c(green, red, pink) -81
5 shape c(circle, triangle) 5
6 shape c(rectangle) 31
This works as well if you replace 'red' with 'blue' or with 'rectangle'. For the extended question in your comment: One could create a vector with the targets (such as c( "red", "triangle" ), then loop over the code above, writing each output into a list. More sample data and information about your desired output would be needed, though. As a first step, you could try:
crit <- c( "rectangle", "red", "blue" ) # vector with target values
y <- list() # initialize receiving list
for( j in 1 : length( crit ) )
{
target <- grep( crit[ j ], x[ , 2 ] )
stash <- x[ target, ]
stash[ , 3 ] <- stash[ , 3 ] * -1
# Modify `names` as desired:
for( i in 1 : length( stash[ , 1 ] ) )
stash[ i, 1 ] <- paste( stash[ i, 1 ], ( 10 * i + j ), sep = "" )
# write to list element instead of overwriting original dataframe
y[[ j ]] <- rbind( x, stash )
y[[ j ]][ target, 3 ] <- 0 # Set the value of the original rows to `0`
y[[ j ]] <- y[[ j ]][ order( y[[ j ]][ 1 ] ), ]
# here, you have a list with individual dataframes for each target value
# you could merge into one joint dataframe with
z <- Reduce( function( x, y, ... ) merge( x, y, all = TRUE, ... ), y )
}
That produces
> z
names variables value
1 colour c(green, red, pink) 0
2 colour c(green, red, pink) 81
3 colour c(pink, purple) 14
4 colour c(red, blue) 0
5 colour c(red, blue) 10
6 colour c(yellow, blue) 0
7 colour c(yellow, blue) 32
8 colour12 c(red, blue) -10
9 colour13 c(red, blue) -10
10 colour22 c(green, red, pink) -81
11 colour23 c(yellow, blue) -32
12 shape c(circle, triangle) 5
13 shape c(rectangle) 0
14 shape c(rectangle) 31
15 shape11 c(rectangle) -31
and may be a good start for further work