-3

The data frame looks like this (the dots are supposed to be vertical dots):

Class IncreasingNumber
"A"   3          <- row 1
"A"   5          <- row 2
...   ...
"A"   20         <-row 31
"B"   1          
"B"   2
... ...
"B"  41          <- row 63
"C"  1
......

There are 20 different classes. The number of rows within each class equals 31.

What I wan to do is quite simple. For each class, I want to insert 3 new rows between all rows. So, we want to insert 3 new rows between row 1 and row 2, and yet 3 others in between row 2 and row 3, all the way up to 3 three new rows between row 30 and 31. But NO new rows between row 31 and 32, since these belong to a different class.

We want to do this for every class.

The three rows which we insert has the same Class as its surrounding rows, and the IncreasingNumber value for those three rows are just the 3 equally spaced points within the IncreasingNumber values for the surrounding points.

For example, for the first class, and for the first three rows to be inserted between row 1 and row 2, we see that the IncreasingNumbers are 3 and 5.

Therefore, the first value for the first row that we insert should be 3.5. The next value should be 4. The third value should be 4.5.

So we should get something like this for the first two classes:

Class IncreasingNumber
"A"   3          
"A"   3.5        <- new row
"A"   4          <- new row
"A"   4.5        <- new row
"A"   5          
...   ...
"A"   20         
"B"   1    
"B"   1.25       <- new row
"B"   1.5        <- new row
"B"   1.75       <- new row
"B"   2
... ...
"B"  41          
"C"  1
Jaap
  • 81,064
  • 34
  • 182
  • 193
Meso owe
  • 21
  • 1
  • 10
    It isn't necessary to be rude. Although you formulated your question pretty well for a new user, you improve it by making the example data better reproducible. See also the Q&A about how to give a [reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example/5963610). – Jaap Mar 20 '18 at 11:31
  • 3
    https://stackoverflow.com/help/be-nice – zx8754 Mar 20 '18 at 11:55
  • 4
    Please be more respectful. We have a ["Be Nice"](http://stackoverflow.com/help/be-nice) policy for a reason. Show us what you have tried. We’re not going to do your work for you, but we are happy to help if you at least make an effort. – elixenide Mar 20 '18 at 12:14
  • Hi @Meso owe. Because you are new to SO, you may have a look [here](https://stackoverflow.com/help/someone-answers) – Henrik Mar 26 '18 at 16:32

2 Answers2

4

You may interpolate the points with approx and its n argument. Using Jaap's data:

library(data.table)    
setDT(df)
df[ , approx(inc.num, n = (.N - 1) * 4 + 1), by = classes]
#     classes    x     y
#  1:       A 1.00  3.00
#  2:       A 1.25  3.50
#  3:       A 1.50  4.00
#  4:       A 1.75  4.50
#  5:       A 2.00  5.00
#  6:       A 2.25  5.25
#  7:       A 2.50  5.50
#  8:       A 2.75  5.75
#  9:       A 3.00  6.00
# 10:       A 3.25  7.00
# 11:       A 3.50  8.00
# 12:       A 3.75  9.00
# 13:       A 4.00 10.00
# 14:       B 1.00  1.00
# 15:       B 1.25  1.25
# 16:       B 1.50  1.50
# 17:       B 1.75  1.75
# 18:       B 2.00  2.00
# 19:       B 2.25  4.00
# 20:       B 2.50  6.00
# 21:       B 2.75  8.00
# 22:       B 3.00 10.00 
David Arenburg
  • 91,361
  • 17
  • 137
  • 196
Henrik
  • 65,555
  • 14
  • 143
  • 159
3

A possible solution with the data.table-package:

library(data.table)

setDT(df)[, .(inc.num.new = unique(c(mapply(function(x, y) seq(from = x, to = y, length.out = 5),
                                            head(inc.num,-1), tail(inc.num,-1)))))
          , by = classes]

which gives:

    classes inc.num.new
 1:       A        3.00
 2:       A        3.50
 3:       A        4.00
 4:       A        4.50
 5:       A        5.00
 6:       A        5.25
 7:       A        5.50
 8:       A        5.75
 9:       A        6.00
10:       A        7.00
11:       A        8.00
12:       A        9.00
13:       A       10.00
14:       B        1.00
15:       B        1.25
16:       B        1.50
17:       B        1.75
18:       B        2.00
19:       B        4.00
20:       B        6.00
21:       B        8.00
22:       B       10.00

Used data:

df <- data.frame(classes = rep(LETTERS[1:2], c(4,3)), inc.num = c(3,5,6,10,1,2,10))
Jaap
  • 81,064
  • 34
  • 182
  • 193
  • And I was lucky to just copy-paste your toy data - that's my small benefit of being a SGIW! ;) – Henrik Mar 20 '18 at 14:43
  • @Henrik haha! btw, I didn't know the `approx`-function; your approach is much clearer; I needed 5 functions to get the desired result .... – Jaap Mar 20 '18 at 14:57