这里的数据
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情景
如果我理解正确的话,那么,方案如下:
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)
如果我理解正确的话,OP希望通过零和一的模式在他的数据集中的不同群体分类action
列。 在这个问题,他描述了几种模式,他预计该数据(称为“情景”)找到。
到目前为止,这个问题被编辑两次以增加更多的场景。 这表明,OP的场景列表可能是不完整的。 因此,我建议了不同的方法,它定义一组完整的场景(或模式0
和1
),然后试图找到在数据集中这些模式。
定义可能出现的情况
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
,例如, 0001000
或00011000
或00011111000
。 方案名称0-0
行2表示另一其中,所述图案仅由特例1
秒。
按组数据集中查找模式
现在,我们可以尝试找出给定的数据模式。 为了寻找不同的模式,我们
- 折叠
action
柱成字符串,分别对每个code
, item
组, - 统计每个的出现
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"