Adding intermediate observations to a data frame (manual interpolating)

65 views Asked by At

I've got a data frame like below with vector coordinates:

df <- structure(list(x0 = c(22.6, 38.5, 73.7), y0 = c(62.9, 56.6, 27.7
), x1 = c(45.8, 49.3, 80.8), y1 = c(69.9, 21.9, 14)), row.names = c(NA, 
-3L), class = c("tbl_df", "tbl", "data.frame"))
# A tibble: 3 x 4
     x0    y0    x1    y1
  <dbl> <dbl> <dbl> <dbl>
1  22.6  62.9  45.8  69.9
2  38.5  56.6  49.3  21.9
3  73.7  27.7  80.8  14 

For visualisation purposes I need to manually interpolate points, i.e. add an intermediate row between each two rows of df, where the starting coordinates x0, y0 are the ending coordinates of original, previous row, while ending coordinates x1, y1 are the starting coordinates of original, next row. I also need to preserve information if an observation is from original dataset or it is manually added. So the expected output would be:

# A tibble: 5 x 5
      x     y pass_end_x pass_end_y source  
  <dbl> <dbl>      <dbl>      <dbl> <chr>   
1  22.6  62.9       45.8       69.9 original
2  45.8  69.9       38.5       56.6 added   
3  38.5  56.6       49.3       21.9 original
4  49.3  21.9       73.7       27.7 added   
5  73.7  27.7       80.8       14   original

How can I do that in efficient and elegant way (preferably in tidyverse)?

1

There are 1 answers

0
Mako212 On

To do this, all I'm going to do is swap the column names of the start and end points, and then use lead to get the next value of x1 and y1. Then we just add the source tag, and bind_rows

library(tidyverse)

df2 <- df

names(df2) <- names(df2)[c(3,4,1,2)] # swap names

df2 <- df2 %>% mutate(x1 = lead(x1), y1 = lead(y1),source = "added")

df <- df %>% mutate(source = "original") %>% bind_rows(., df2)

Resulting in:

# A tibble: 6 x 5
     x0    y0    x1    y1 source  
  <dbl> <dbl> <dbl> <dbl> <chr>   
1  22.6  62.9  45.8  69.9 original
2  38.5  56.6  49.3  21.9 original
3  73.7  27.7  80.8  14   original
4  45.8  69.9  38.5  56.6 added   
5  49.3  21.9  73.7  27.7 added   
6  80.8  14    NA    NA   added  

If you need the rows in order:

df2 <- df2 %>% mutate(x1 = lead(x1), y1 = lead(y1),source = "added", ID = seq(1,n()*2, by =2)+1)

df <- df %>% mutate(source = "original", ID = seq(1,n()*2, by =2)) %>% bind_rows(., df2) %>% arrange(ID)

# A tibble: 6 x 6
     x0    y0    x1    y1 source      ID
  <dbl> <dbl> <dbl> <dbl> <chr>    <dbl>
1  22.6  62.9  45.8  69.9 original     1
2  45.8  69.9  38.5  56.6 added        2
3  38.5  56.6  49.3  21.9 original     3
4  49.3  21.9  73.7  27.7 added        4
5  73.7  27.7  80.8  14   original     5
6  80.8  14    NA    NA   added        6