通过其中的R脚本选择基(selecting groups by its scenario in R)

2019-09-27 10:46发布

这里的数据

mydat=structure(list(code = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L), .Label = "52382МСК", class = "factor"), 
    item = c(11709L, 11709L, 11709L, 11709L, 11708L, 11708L, 
    11708L, 11710L, 11710L, 11710L, 11710L, 11710L, 11710L, 11710L, 
    11710L, 11710L, 11710L, 11710L, 11710L, 11710L, 11710L, 11710L, 
    11710L, 11710L, 11710L, 11710L, 11710L, 11710L), sales = c(30L, 
    10L, 20L, 15L, 2L, 10L, 3L, 30L, 10L, 20L, 15L, 2L, 10L, 
    3L, 30L, 10L, 20L, 15L, 2L, 10L, 3L, 30L, 10L, 20L, 15L, 
    2L, 10L, 3L), action = c(0L, 1L, 0L, 0L, 0L, 1L, 0L, 0L, 
    0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 
    0L, 1L, 0L, 0L, 0L)), .Names = c("code", "item", "sales", 
"action"), class = "data.frame", row.names = c(NA, -28L))

我有3组乏代码+项目。 这3组:

code    item
52382МСК    11709
52382МСК    11708
52382МСК    11710

另外我有行动列。 它只能有两个值零(0)或一(1)。

每个基团代表3个场景

52382МСК    11709

它是情景时,我们有1零类动作山坳。 行动之前山坳第一类和动作山坳第一类后两个零。 注:也许情况下,当我们有2个零类动作山坳。 前动作栏的第一类别,和动作栏的第一类后1为零。

52382МСК    11708

它是情景时,我们有1零类动作山坳。 和行动山坳第一类后1个零。

52382МСК    11710

它是情景时,我们有3个(含)以上零类动作山坳。 和行动山口的第一类后3(或更多)个零。

如何选择具有每个场景的群体? 即Mydat1它与第一场景组, Mydat2它与第二场景组,并且Mydat3它与第三情景组

输出很简单

mydat1

code    item    sales   action
52382МСК    11709   30  0
52382МСК    11709   10  1
52382МСК    11709   20  0
52382МСК    11709   15  0



mydat2
code    item    sales   action
52382МСК    11708   2   0
52382МСК    11708   10  1
52382МСК    11708   3   0

mydat3
code    item    sales   action
52382МСК    11710   30  0
52382МСК    11710   10  0
52382МСК    11710   20  0
52382МСК    11710   15  1
52382МСК    11710   2   0
52382МСК    11710   10  0
52382МСК    11710   3   0
52382МСК    11710   30  0
52382МСК    11710   10  0
52382МСК    11710   20  0
52382МСК    11710   15  1
52382МСК    11710   2   0
52382МСК    11710   10  0
52382МСК    11710   3   0
52382МСК    11710   30  0
52382МСК    11710   10  0
52382МСК    11710   20  0
52382МСК    11710   15  1
52382МСК    11710   2   0
52382МСК    11710   10  0
52382МСК    11710   3   0

编辑

我忘了,它可以是场景,当我们有1零类动作山坳。 行动之前山坳第一类和动作山坳第一类后三个零。 也许场景时,我们有3个零类动作山坳。 前动作栏的第一类别,和动作栏的第一类后1为零。

(mydat4)

还可以的情况时,我们有2个零类动作山坳。 行动之前山坳第一类和动作山坳第一类后三个零。 也许场景时,我们有3个零类动作山坳。 前动作栏的第一类别,和2个零动作栏的第一类后。

(mydat5)

IE浏览器就必须工作,只能用这些场景。

EDIT2

我发现了一个组,它只有一行

code    item    sales   action
52499МСК    11202   2   0

如何做到这一点,如果数据仅有一行这将是6情景?

也可以如此

code    item    sales   action
52499МСК    11202   2   0
 52499МСК   11202   2   1

要么

code    item    sales   action
52499МСК    11202   2   0
 52499МСК   11202   2   0

要么

code    item    sales   action
52499МСК    11202   2   1
 52499МСК   11202   2   1

如果我们在小组只有两排,然后7情景

Answer 1:

如果我理解正确的话,那么,方案如下:

S1:0100
S2:010
S3:000 ... 1000 ...
S4:01000或00010
S5:001000或000100
S6:0或1
S7:01或00或10或11

如果是这样,那么方便每种方案都有行的唯一计数。 S1是4行,s2为3,S3是7+,S4是5,S5是6,S6是1,和S7为2。

使用的事实,我们可以做到以下几点:

library(dplyr)

mydat = structure(list(code = c("52382MCK", "52382MCK", "52382MCK", "52382MCK", 
"52382MCK", "52382MCK", "52382MCK", "52382MCK", "52382MCK", "52382MCK", 
"52382MCK", "52382MCK", "52382MCK", "52382MCK", "52382MCK", "52382MCK", 
"52382MCK", "52382MCK", "52382MCK", "52382MCK", "52382MCK", "52382MCK", 
"52382MCK", "52382MCK", "52382MCK", "52382MCK", "52382MCK", "52382MCK"
), item = c(11709L, 11709L, 11709L, 11709L, 11708L, 11708L, 11708L, 
11710L, 11710L, 11710L, 11710L, 11710L, 11710L, 11710L, 11710L, 
11710L, 11710L, 11710L, 11710L, 11710L, 11710L, 11710L, 11710L, 
11710L, 11710L, 11710L, 11710L, 11710L), sales = c(30L, 10L, 
20L, 15L, 2L, 10L, 3L, 30L, 10L, 20L, 15L, 2L, 10L, 3L, 30L, 
10L, 20L, 15L, 2L, 10L, 3L, 30L, 10L, 20L, 15L, 2L, 10L, 3L), 
    action = c(0L, 1L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 
    0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 
    0L)), class = "data.frame", row.names = c(NA, -28L), .Names = c("code", 
"item", "sales", "action"))

mydat = mydat %>%
  group_by(code, item) %>%
  mutate(groups_item_count = n(),
         scenario = case_when(groups_item_count == 4 ~ 1,
                              groups_item_count == 3 ~ 2,
                              groups_item_count >= 7 ~ 3,
                              groups_item_count == 5 ~ 4,
                              groups_item_count == 6 ~ 5,
                              groups_item_count == 1 ~ 6,
                              groups_item_count == 2 ~ 7))

这将添加一个“方案”列将表明无论是场景1,2,3,4或5。我强烈建议你不要打破你的数据帧分成多个数据帧。 我愿意猜测,dplyr的filter()group_by()函数将是实现更高效的无论是你接下来要完成的任务。 但是,如果你在分手为每个场景单独的数据帧坚决,那么你可以这样做:

mydat1 = filter(mydat, scenario == 1)
mydat2 = filter(mydat, scenario == 2)
mydat3 = filter(mydat, scenario == 3)
mydat4 = filter(mydat, scenario == 4)
mydat5 = filter(mydat, scenario == 5)
mydat6 = filter(mydat, scenario == 6)
mydat7 = filter(mydat, scenario == 7)


Answer 2:

如果我理解正确的话,OP希望通过零和一的模式在他的数据集中的不同群体分类action列。 在这个问题,他描述了几种模式,他预计该数据(称为“情景”)找到。

到目前为止,这个问题被编辑两次以增加更多的场景。 这表明,OP的场景列表可能是不完整的。 因此,我建议了不同的方法,它定义一组完整的场景(或模式01 ),然后试图找到在数据集中这些模式。

定义可能出现的情况

IIUC,不同的场景取决于连续数0之前和每一序列或条纹之后小号1秒。 (在这个问题的样本数据集只具有单一的1秒,但在OP已经张贴在该数据包含多达三个的条纹相关问题1秒。)

据OP的描述有可能是无0或最多三个连续的序列0年代以前或连胜后1秒。 此外,一个组可以包含仅0秒。

有了这个,所有可能的模式的表/可以创建情景:

library(data.table)
library(magrittr)

max_zeros <- 3
zeros <- sapply(0:max_zeros, stringr::str_dup, string = "0")
names(zeros) <- as.character(nchar(zeros))
sc <- CJ(zeros.before = zeros, zeros.after = zeros)[
  , scenario.name := paste(nchar(zeros.before), nchar(zeros.after), sep = "-")][
    , action.pattern := sprintf("%s1+(?=%s)", zeros.before, zeros.after)][]
# special case: all zero
sc0 <- data.table(
  zeros.before = NA,
  zeros.after = NA, 
  scenario.name = "no1", 
  action.pattern = "^0+$")
sc <- rbind(sc0, sc)
sc
  zeros.before zeros.after scenario.name action.pattern 1: <NA> <NA> no1 ^0+$ 2: 0-0 1+(?=) 3: 0 0-1 1+(?=0) 4: 00 0-2 1+(?=00) 5: 000 0-3 1+(?=000) 6: 0 1-0 01+(?=) 7: 0 0 1-1 01+(?=0) 8: 0 00 1-2 01+(?=00) 9: 0 000 1-3 01+(?=000) 10: 00 2-0 001+(?=) 11: 00 0 2-1 001+(?=0) 12: 00 00 2-2 001+(?=00) 13: 00 000 2-3 001+(?=000) 14: 000 3-0 0001+(?=) 15: 000 0 3-1 0001+(?=0) 16: 000 00 3-2 0001+(?=00) 17: 000 000 3-3 0001+(?=000) 

action.pattern正则表达式 ,其被用于找到其通过折叠所创建的在字符串模式action为每个组列。 它采用lookahead找到重叠的图案。

scenario.name是图案的简短描述。 例如,场景名3-3行17表示,其由三个的图案0 ,的一个或多个条纹1 S,接着是三个0 ,例如, 00010000001100000011111000 。 方案名称0-0行2表示另一其中,所述图案仅由特例1秒。

按组数据集中查找模式

现在,我们可以尝试找出给定的数据模式。 为了寻找不同的模式,我们

  • 折叠action柱成字符串,分别对每个codeitem组,
  • 统计每个的出现action.pattern字符串中,和
  • 格式化结果以宽格式(一行的每个组)。

请注意, mydat已经被修改为包括来自OP的编辑(见下文数据部分)的额外的使用情况。

mydat[, paste(action, collapse = "") %>% 
        stringr::str_count(sc$action.pattern) %>%
        t() %>% 
        as.data.table() %>% 
        setnames(sc$scenario.name),
      by = .(code, item)]

       code  item no1 0-0 0-1 0-2 0-3 1-0 1-1 1-2 1-3 2-0 2-1 2-2 2-3 3-0 3-1 3-2 3-3
1: 52382MCK 11709   0   1   1   1   0   1   1   1   0   0   0   0   0   0   0   0   0
2: 52382MCK 11708   0   1   1   0   0   1   1   0   0   0   0   0   0   0   0   0   0
3: 52382MCK 11710   0   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3
4: 52499MCK 11202   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
5: 52499MCK 11203   0   1   0   0   0   1   0   0   0   0   0   0   0   0   0   0   0
6: 52499MCK 11204   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
7: 52499MCK 11205   0   1   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0

该表显示了可能的模式/场景是每个组中的“隐藏”,以及如何被发现的许多事件。

例如,第2行示出了相应的组中的图案0-0"1" 0-1"10" 1-0"01"1-1"010 )已经发现各1次。找到的所有图案, 1-1"010 )是最长的,所以我们将以此作为分类该组。

第3行显示,几乎所有的模式已经被发现三次各自的小组。 然而,图案3-3"0001000" )是最长的,并且将被视为分类为这组。

组的自动分类

我们可以选择右侧的图案为自动一组分类:

class <- mydat[, .(scenario.name = sc$scenario.name[
  paste(action, collapse = "") %>% 
    stringr::str_count(sc$action.pattern) %>%
    is_greater_than(0) %>% 
    which() %>% 
    max()
  ]),
  by = .(code, item)][]

class
  code item scenario.name 1: 52382MCK 11709 1-2 2: 52382MCK 11708 1-1 3: 52382MCK 11710 3-3 4: 52499MCK 11202 no1 5: 52499MCK 11203 1-0 6: 52499MCK 11204 no1 7: 52499MCK 11205 0-0 

分类还可以通过连接到的每一行mydat

mydat[class, on = .(code, item)]
  code item sales action scenario.name 1: 52382MCK 11709 30 0 1-2 2: 52382MCK 11709 10 1 1-2 3: 52382MCK 11709 20 0 1-2 4: 52382MCK 11709 15 0 1-2 5: 52382MCK 11708 2 0 1-1 6: 52382MCK 11708 10 1 1-1 7: 52382MCK 11708 3 0 1-1 8: 52382MCK 11710 30 0 3-3 9: 52382MCK 11710 10 0 3-3 10: 52382MCK 11710 20 0 3-3 11: 52382MCK 11710 15 1 3-3 12: 52382MCK 11710 2 0 3-3 13: 52382MCK 11710 10 0 3-3 14: 52382MCK 11710 3 0 3-3 15: 52382MCK 11710 30 0 3-3 16: 52382MCK 11710 10 0 3-3 17: 52382MCK 11710 20 0 3-3 18: 52382MCK 11710 15 1 3-3 19: 52382MCK 11710 2 0 3-3 20: 52382MCK 11710 10 0 3-3 21: 52382MCK 11710 3 0 3-3 22: 52382MCK 11710 30 0 3-3 23: 52382MCK 11710 10 0 3-3 24: 52382MCK 11710 20 0 3-3 25: 52382MCK 11710 15 1 3-3 26: 52382MCK 11710 2 0 3-3 27: 52382MCK 11710 10 0 3-3 28: 52382MCK 11710 3 0 3-3 29: 52499MCK 11202 2 0 no1 30: 52499MCK 11203 2 0 1-0 31: 52499MCK 11203 2 1 1-0 32: 52499MCK 11204 2 0 no1 33: 52499MCK 11204 2 0 no1 34: 52499MCK 11205 2 1 0-0 35: 52499MCK 11205 2 1 0-0 code item sales action scenario.name 

警告

答案是基于我的任择议定书的要求的理解,包括对OP的生产数据集诸多猜测和隐含假设。

数据

加强版mydat

mydat <- 
structure(list(code = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("52382MCK", 
"52499MCK"), class = "factor"), item = c(11709L, 11709L, 11709L, 
11709L, 11708L, 11708L, 11708L, 11710L, 11710L, 11710L, 11710L, 
11710L, 11710L, 11710L, 11710L, 11710L, 11710L, 11710L, 11710L, 
11710L, 11710L, 11710L, 11710L, 11710L, 11710L, 11710L, 11710L, 
11710L, 11202L, 11203L, 11203L, 11204L, 11204L, 11205L, 11205L
), sales = c(30L, 10L, 20L, 15L, 2L, 10L, 3L, 30L, 10L, 20L, 
15L, 2L, 10L, 3L, 30L, 10L, 20L, 15L, 2L, 10L, 3L, 30L, 10L, 
20L, 15L, 2L, 10L, 3L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), action = c(0L, 
1L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 
1L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 
1L, 1L)), row.names = c(NA, -35L), class = "data.frame")
# coerce to data.table
setDT(mydat)

编辑:分裂的情景

该OP已要求创建为每个17个场景一个单独的数据集。

在一般情况下,我不建议,除非有充分的理由,额外的要求,或外部约束采用这种做法。 试想一下,你是一个数据库管理员。 你想在你的数据库中创建17个不同结构相同的表,而不是一个表,其中处理可以通过选择子集来控制的?

然而,有这样的可能性split()的情况下的数据集:

split(mydat[class, on = .(code, item)], by = "scenario.name")
 $`1-2` code item sales action scenario.name 1: 52382MCK 11709 30 0 1-2 2: 52382MCK 11709 10 1 1-2 3: 52382MCK 11709 20 0 1-2 4: 52382MCK 11709 15 0 1-2 $`1-1` code item sales action scenario.name 1: 52382MCK 11708 2 0 1-1 2: 52382MCK 11708 10 1 1-1 3: 52382MCK 11708 3 0 1-1 $`3-3` code item sales action scenario.name 1: 52382MCK 11710 30 0 3-3 2: 52382MCK 11710 10 0 3-3 3: 52382MCK 11710 20 0 3-3 4: 52382MCK 11710 15 1 3-3 5: 52382MCK 11710 2 0 3-3 6: 52382MCK 11710 10 0 3-3 7: 52382MCK 11710 3 0 3-3 8: 52382MCK 11710 30 0 3-3 9: 52382MCK 11710 10 0 3-3 10: 52382MCK 11710 20 0 3-3 11: 52382MCK 11710 15 1 3-3 12: 52382MCK 11710 2 0 3-3 13: 52382MCK 11710 10 0 3-3 14: 52382MCK 11710 3 0 3-3 15: 52382MCK 11710 30 0 3-3 16: 52382MCK 11710 10 0 3-3 17: 52382MCK 11710 20 0 3-3 18: 52382MCK 11710 15 1 3-3 19: 52382MCK 11710 2 0 3-3 20: 52382MCK 11710 10 0 3-3 21: 52382MCK 11710 3 0 3-3 code item sales action scenario.name $no1 code item sales action scenario.name 1: 52499MCK 11202 2 0 no1 2: 52499MCK 11204 2 0 no1 3: 52499MCK 11204 2 0 no1 $`1-0` code item sales action scenario.name 1: 52499MCK 11203 2 0 1-0 2: 52499MCK 11203 2 1 1-0 $`0-0` code item sales action scenario.name 1: 52499MCK 11205 2 1 0-0 2: 52499MCK 11205 2 1 0-0 

其结果是列表的data.tables。

单元素可以从列表中拾取

split(mydat[class, on = .(code, item)], by = "scenario.name")[["1-2"]]
  code item sales action scenario.name 1: 52382MCK 11709 30 0 1-2 2: 52382MCK 11709 10 1 1-2 3: 52382MCK 11709 20 0 1-2 4: 52382MCK 11709 15 0 1-2 

如果仍然需要某种原因杂波与许多单个数据对象的工作区这是可以做到如下( 不推荐

# workspace before
ls()
[1] "class"     "max_zeros" "mydat"     "sc"        "sc0"       "zeros"   
# create separate datasets
mydat[class, on = .(code, item)] %>% 
  split(by = "scenario.name") %>% 
  set_names(names(.) %>% make.names()) %>%   # make syntactically valid names 
  list2env(.GlobalEnv)
<environment: R_GlobalEnv> 
#workspace after
ls()
  [1] "class" "max_zeros" "mydat" "no1" "sc" "sc0" "X0.0" [8] "X1.0" "X1.1" "X1.2" "X3.3" "zeros" 


文章来源: selecting groups by its scenario in R