Вставить строки на основе разницы между значением из строки N столбца A и строки N + 1 столбца B - PullRequest
1 голос
/ 04 февраля 2020

У меня есть данные в следующем примере (я использую R):

A   B   C
1   2   Background
3   19  Background
26  41  person
43  69  person
83  97  Background
107 129 Background
132 179 Background
189 235 Background
243 258 Background
261 279 person

Я хотел бы добавить строки, где разница между строкой A col N + 1 и строкой B B N> 1 и строка C получает метку (например, «другое»). Таким образом, данные будут выглядеть так:

A   B   C
1   2   Background
3   19  Background
20  25  other
26  41  person
43  69  person
70  82  other
83  97  Background
98  106 other
107 129 Background
130 131 other
132 179 Background
180 188 other
189 235 Background
236 242 other
243 258 Background
259 260 other
261 279 person

Спасибо!

Ответы [ 2 ]

3 голосов
/ 04 февраля 2020

Вот один способ использования базы R, предполагая, что значение 4-й строки A равно 42 (а не 43).

#Find out row indices where difference of A value for N + 1 row and 
#B value in N row is not equal to 1.
inds <- which(tail(df$A, -1) - head(df$B, -1) != 1)
#Create a dataframe which we want to insert in the current dataframe
#using values from A and B colummn and inds indices
include_df <- data.frame(A = df$B[inds] + 1,B = df$A[inds + 1] - 1, C = 'other', 
               stringsAsFactors = FALSE)
#Repeat rows at inds to make space to insert new rows
df <- df[sort(c(seq_len(nrow(df)), inds)), ]
#Insert the new rows in their respective position
df[inds + seq_along(inds), ] <- include_df
#Remove row names
row.names(df) <- NULL

df
#     A   B          C
#1    1   2 Background
#2    3  19 Background
#3   20  25      other
#4   26  41     person
#5   42  69     person
#6   70  82      other
#7   83  97 Background
#8   98 106      other
#9  107 129 Background
#10 130 131      other
#11 132 179 Background
#12 180 188      other
#13 189 235 Background
#14 236 242      other
#15 243 258 Background
#16 259 260      other
#17 261 279     person

data

df <- structure(list(A = c(1, 3, 26, 42, 83, 107, 132, 189, 243, 261
), B = c(2L, 19L, 41L, 69L, 97L, 129L, 179L, 235L, 258L, 279L
), C = c("Background", "Background", "person", "person", "Background", 
"Background", "Background", "Background", "Background", "person"
)), row.names = c(NA, -10L), class = "data.frame")
0 голосов
/ 04 февраля 2020

Опция, использующая data.table с использованием того же редактирования данных, что и Ronak:

ix <- DT[shift(A, -1L) - B > 1L, which=TRUE]
rbindlist(list(DT,
    data.table(A=DT$B[ix]+1L, B=DT$A[ix+1L]-1L, C="other")))[order(A)]

Вывод:

      A   B          C
 1:   1   2 Background
 2:   3  19 Background
 3:  20  25      other
 4:  26  41     person
 5:  42  69     person
 6:  70  82      other
 7:  83  97 Background
 8:  98 106      other
 9: 107 129 Background
10: 130 131      other
11: 132 179 Background
12: 180 188      other
13: 189 235 Background
14: 236 242      other
15: 243 258 Background
16: 259 260      other
17: 261 279     person

Данные:

library(data.table)
DT <- fread("A   B   C
1   2   Background
3   19  Background
26  41  person
42  69  person
83  97  Background
107 129 Background
132 179 Background
189 235 Background
243 258 Background
261 279 person")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...