Удалить 2 последовательных строки, соответствующих условию - PullRequest
0 голосов
/ 24 сентября 2018

Вот ссылка на транзакцию.это сценарий отмененной транзакции в проверке ресторана.

Я хочу, чтобы R проверил, есть ли у элемента флаг "U", затем удалите U и 1 аналогичный элемент, который не является u.

Я пометил элементы для удаления желтым цветом.

chk_num dtl_name    Duration    Guest   void_type   Item_ttl
9707    Americano           45  1       18
9707    Americano           45  1       18
9707    Breakfast Tea       45  1       18
9707    Breakfast Tea       45  1   U   -18
9707    Café Latte          45  1       21
9707    Camomille Tea       45  1   U   -18
9707    Camomille Tea       45  1       18
9707    Earl Grey Tea       45  1   U   -18
9707    Earl Grey Tea       45  1       18
9707    Fresh Mint Tea      45  1   U   -18
9707    Fresh Mint Tea      45  1       18
9707    Green Tea           45  1       18
9707    Green Tea           45  1   U   -18
9707    Green Tea           45  1       18
9707    Lemon Tea           45  1       18
9707    Lemon Tea           45  1   U   -18
9707    Orange Juice        45  1       24
9707    Pepper Mint Tea     45  1       18
9707    Pepper Mint Tea     45  1   U   -18

Data base Picture

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

Альтернативное решение с пакетом :

# load the 'data.table'-package & convert 'DF' to a data.table
library(data.table)
setDT(DF)

# add a rownumber
DF[ , rn := .I][]

# create a subset with only the 'U'-rows and make 'Item_ttl' positive
DF_U <- DF[void_type == "U"][, Item_ttl := Item_ttl * -1][]

# create an index of rownumbers to be removed by:
# - extracting 'rn' from 'DF_U'
# - joining DF_U with DF
#   select only the first matching row in the join
#   and then extract 'rn'
# - concatenate these two vectors into one
ix <- c(DF_U$rn, DF[DF_U, on = .(chk_num,dtl_name,Duration,Guest,Item_ttl), mult = "first"]$rn)

Теперь вы можете получить желаемый конечный результат, используя:

DF[!ix]

, что дает:

   chk_num     dtl_name Duration Guest void_type Item_ttl rn
1:    9707    Americano       45     1      <NA>       18  1
2:    9707    Americano       45     1      <NA>       18  2
3:    9707   Café-Latte       45     1      <NA>       21  5
4:    9707    Green-Tea       45     1      <NA>       18 14
5:    9707 Orange-Juice       45     1      <NA>       24 17
0 голосов
/ 24 сентября 2018

Я почти уверен, что есть лучший способ сделать это.

data:

df1<-
data.table::fread("chk_num dtl_name Duration Guest void_type Item_ttl
9707    Americano           45  1   NA  18
9707    Americano           45  1   NA  18
9707    Breakfast-Tea       45  1   NA  18
9707    Breakfast-Tea       45  1   U   -18
9707    Café-Latte          45  1   NA  21
9707    Camomille-Tea       45  1   U   -18
9707    Camomille-Tea       45  1   NA   18
9707    Earl-Grey-Tea       45  1   U   -18
9707    Earl-Grey-Tea       45  1   NA   18
9707    Fresh-Mint-Tea      45  1   U   -18
9707    Fresh-Mint-Tea      45  1   NA   18
9707    Green-Tea           45  1   NA  18
9707    Green-Tea           45  1   U   -18
9707    Green-Tea           45  1   NA  18
9707    Lemon-Tea           45  1   NA  18
9707    Lemon-Tea           45  1   U   -18
9707    Orange-Juice        45  1   NA  24
9707    Pepper-Mint-Tea     45  1   NA  18
9707    Pepper-Mint-Tea     45  1   U   -18") %>% setDF

code:

fun1 <- function(x) {
        while("U" %in% x$void_type) {
            flagU    <- min(which(x$void_type == "U"))
            delFlagU <- min(which(x$Item_ttl == -x$Item_ttl[flagU]))
            x    <- x[-c(flagU,delFlagU),]
            if(!("U" %in% x$void_type)) {return(x)}

        }
        return(x)
    } 

df1 %>% dplyr::group_by(dtl_name, Duration, Guest) %>% dplyr::do(.,fun1(.))

result:

# A tibble: 5 x 6
# Groups:   dtl_name, Duration, Guest [4]
#  chk_num dtl_name     Duration Guest void_type Item_ttl
#    <int> <chr>           <int> <int> <chr>        <int>
#1    9707 Americano          45     1 <NA>            18
#2    9707 Americano          45     1 <NA>            18
#3    9707 Café-Latte         45     1 <NA>            21
#4    9707 Green-Tea          45     1 <NA>            18
#5    9707 Orange-Juice       45     1 <NA>            24

пожалуйста, обратите внимание:

Если у вас есть флаг U, но нет соответствующего «ПАРА», вы застрянете в бесконечном цикле.

Возможно, выхочу немного расширить мой ответ.

Поскольку вы ничего не говорите о своей бизнес-логике, я ничего о ней не знаю.Вы можете адаптировать группировку dplyr::group_by(dtl_name, Duration, Guest).Esp с Duration Я не уверен.


Если вы более data.table парень:

data.table::setDT(df1)[, fun1(.SD), by = .(dtl_name, Duration, Guest)]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...