Добавить строки для пропущенных этапов в процессе - PullRequest
2 голосов
/ 11 апреля 2019

Я хочу взять фрейм данных в R и увеличить его на основе того, что вижу в двух столбцах, V1 и V2. Короче говоря, у меня есть этапы S1-S6, которые являются строками.

Для каждой строки, где есть разрыв в сцене, мне нужно добавить строки. Глядя на кадры данных ниже, если бы я увидел «S 3» и «S 3» в одной строке, мне не нужно было бы ничего делать. Точно так же, если бы я увидел «S 3» и «S 4» в одном ряду, мне бы тоже не пришлось ничего делать.

Пример 1

Введите:

----------------------------------
|Var1               | V1   | V2  |    
----------------------------------
|0060a00000fUbAnAAK |'S 2' |'S 5'|
----------------------------------

Выход:

----------------------------------
|Var1               | V1   | V2  |    
----------------------------------
|0060a00000fUbAnAAK |'S 2' |'S 3'|
----------------------------------
|0060a00000fUbAnAAK |'S 3' |'S 4'|
----------------------------------
|0060a00000fUbAnAAK |'S 4' |'S 5'|
----------------------------------

Пример 2

Введите:

----------------------------------
|Var1               | V1   | V2  |    
----------------------------------
|0060a00000fUbAnAAK |'S 5' |'S 3'|
----------------------------------

Выход:

----------------------------------
|Var1               | V1   | V2  |    
----------------------------------
|0060a00000fUbAnAAK |'S 5' |'S 4'|
----------------------------------
|0060a00000fUbAnAAK |'S 4' |'S 3'|
----------------------------------

Ответы [ 2 ]

0 голосов
/ 11 апреля 2019

обновленный ответ

В этом обновлении также учитываются убывающие этапы

пример данных

library(data.table)
DT <- fread("Var1               | V1   | V2
  0060a00000fUbAnAAK |S 2 |S 5
  0060a00000fUbAnAAK_ |S 5 |S 3")

#                   Var1  V1  V2
# 1:  0060a00000fUbAnAAK S 2 S 5
# 2: 0060a00000fUbAnAAK_ S 5 S 3

код

#determine order of stages
DT[ as.numeric( gsub("[^0-9]", "", V2 ) ) < as.numeric( gsub("[^0-9]", "", V1 ) ), order := "desc" ]
DT[ is.na( order) , order := "asc" ]
#melt DT to long format
DT <- melt( DT, id.vars = c("Var1","order"), value.name = "stage")
#get stage as numeric and clean up unwanted columns
DT[, `:=`(stage = as.numeric( gsub("[^0-9]", "", stage)))]
#create new stages based on minimum and maximum stage per Var1-value
#use different methodes of ascending and descneding stages, then bind the rows together
rbind(
  DT[order == "asc", .( V1 = paste0( "S ", min(stage): (max(stage) - 1 ) ), 
                        V2 = paste0( "S ", (min(stage)+1):max(stage) ) ), by = .(Var1)],
  DT[order == "desc", .( V1 = paste0( "S ", max(stage): (min(stage) + 1 ) ), 
                         V2 = paste0( "S ", (max(stage)-1):min(stage) ) ), by = .(Var1)]
)

вывод

#                   Var1  V1  V2
# 1:  0060a00000fUbAnAAK S 2 S 3
# 2:  0060a00000fUbAnAAK S 3 S 4
# 3:  0060a00000fUbAnAAK S 4 S 5
# 4: 0060a00000fUbAnAAK_ S 5 S 4
# 5: 0060a00000fUbAnAAK_ S 4 S 3

предыдущий ответ

`data.table` solution

**sample data**

    library(data.table)
    DT <- fread("Var1               | V1   | V2
      0060a00000fUbAnAAK |S 2 |S 5")

**code**

    #melt DT to long format
    DT <- melt( DT, id.vars = "Var1", value.name = "stage")
    #get stage as numeric and clean up unwanted columns
    DT[, `:=`(variable = NULL, stage = as.numeric( gsub("[^0-9]", "", stage)))]
    #create new stages based on minimum and maximum stage per Var1-value
    DT[, .( V1 = paste0( "S ", min(stage):(max(stage)-1) ),
            V2 = paste0( "S ", (min(stage)+1):max(stage) ) ), by = .(Var1)][]

**output**

    #                  Var1  V1  V2
    # 1: 0060a00000fUbAnAAK S 2 S 3
    # 2: 0060a00000fUbAnAAK S 3 S 4
    # 3: 0060a00000fUbAnAAK S 4 S 5
0 голосов
/ 11 апреля 2019

Идея использования tidyverse - преобразовать в длинный формат, отделить числа от S и завершить последовательность.Получив это, мы вставляем столбцы обратно (S и values) и конвертируем обратно в широкоформатный формат.Наконец, мы берем отстающую переменную V1 и удаляем NA с, то есть

library(tidyverse)

df %>% 
 gather(var, val, -1) %>% 
 separate(val, into = c('char', 'number'), sep = ' ') %>% 
 mutate(number = as.numeric(number)) %>% 
 complete(nesting(var, Var1, char), number = full_seq(min(number):max(number), 1)) %>%
 unite('V1_2', c('char', 'number'), sep = ' ') %>% 
 group_by(var) %>% 
 mutate(new = row_number()) %>% 
 spread(var, V1_2) %>% 
 mutate(V1 = lag(V1)) %>% 
 na.omit() %>% 
 select(-new)

, что дает

# A tibble: 3 x 3
   Var1  V1    V2   
  <chr> <chr> <chr>
1 xxx   S 2   S 3  
2 xxx   S 3   S 4  
3 xxx   S 4   S 5 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...