#r #dataframe #analytics
#r #фрейм данных #аналитика
Вопрос:
Я хочу взять фрейм данных в 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'|
----------------------------------
Ответ №1:
Идея использования tidyverse
заключается в преобразовании в длинный формат, отделении чисел от S
последовательности и завершении. Как только мы получим это, мы вставляем столбцы обратно вместе ( S
и values
) и преобразуем обратно в широкий формат. Наконец, мы берем запаздывающую переменную V1
и удаляем NA
s, т.е.
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
Ответ №2:
обновленный ответ
Это обновление также учитывает уменьшение этапов
пример данных
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
Комментарии:
1. обновление alse обрабатывает уменьшающиеся этапы, как указано в
example 2
вопросе