R “嵌套”的问题;ifelse();通过“引用”引用上一行;shift();

R “嵌套”的问题;ifelse();通过“引用”引用上一行;shift();,r,data.table,R,Data.table,我试图使用嵌套的ifelse()和shift()将各种业务逻辑应用于源数据集,但我的代码给出了我不理解的结果。问题陈述如下:我有一个包含“CustomerID”、“Month”和“Status”的客户数据集 我需要通过应用以下逻辑创建第三列“旅程状态” #初始化每个客户的第一条记录。 示例1$tourney\u Status=ifelse(!重复(示例1[,c(“CustomerID”)]),示例1$Status,“”) 示例1[,旅程状态:=ifelse(重复(客户ID), ifelse(班次

我试图使用嵌套的ifelse()和shift()将各种业务逻辑应用于源数据集,但我的代码给出了我不理解的结果。问题陈述如下:我有一个包含“CustomerID”、“Month”和“Status”的客户数据集

我需要通过应用以下逻辑创建第三列“旅程状态”

#初始化每个客户的第一条记录。
示例1$tourney\u Status=ifelse(!重复(示例1[,c(“CustomerID”)]),示例1$Status,“”)
示例1[,旅程状态:=ifelse(重复(客户ID),
ifelse(班次(行程状态,1,type=“lag”)=“A”&
%c(“A”、“B”、“c”、“D”)中的状态%,
地位
ifelse(班次(行程状态,1,type=“lag”)=“B”&
%c(“B”、“c”、“D”)中的状态%,
地位
ifelse(班次(行程状态,1,type=“lag”)=“C”&
%c(“c”、“D”)中的状态%,
地位
ifelse(班次(行程状态,1,type=“lag”)=“D”&
%c(“D”)中的状态%,
地位
班次(行程_状态,1,type=“lag”;”),
旅程状态][]
我希望看到以下情况:

CustomerID  Month   Status  Journey_Status
43210       1/1/18  A       A
43210       2/1/18  B       B
43210       3/1/18  A       B
43210       4/1/18  B       B
43210       5/1/18  C       C
43210       6/1/18  D       D
43210       7/1/18  B       D
6543        1/1/19  C       C
6543        2/1/19  D       D
6543        3/1/19  A       D
6543        4/1/19  B       D
6543        5/1/19  C       D
6543        6/1/19  A       D
CustomerID  Month   Status  Journey_Status
43210       1/1/18  A       A
43210       2/1/18  B       B
43210       3/1/18  A       
43210       4/1/18  B       
43210       5/1/18  C       
43210       6/1/18  D       
43210       7/1/18  B       
6543        1/1/19  C       C
6543        2/1/19  D       D
6543        3/1/19  A       
6543        4/1/19  B       
6543        5/1/19  C       
6543        6/1/19  A       
相反,我得到了以下信息:

CustomerID  Month   Status  Journey_Status
43210       1/1/18  A       A
43210       2/1/18  B       B
43210       3/1/18  A       B
43210       4/1/18  B       B
43210       5/1/18  C       C
43210       6/1/18  D       D
43210       7/1/18  B       D
6543        1/1/19  C       C
6543        2/1/19  D       D
6543        3/1/19  A       D
6543        4/1/19  B       D
6543        5/1/19  C       D
6543        6/1/19  A       D
CustomerID  Month   Status  Journey_Status
43210       1/1/18  A       A
43210       2/1/18  B       B
43210       3/1/18  A       
43210       4/1/18  B       
43210       5/1/18  C       
43210       6/1/18  D       
43210       7/1/18  B       
6543        1/1/19  C       C
6543        2/1/19  D       D
6543        3/1/19  A       
6543        4/1/19  B       
6543        5/1/19  C       
6543        6/1/19  A       

我没有看到正在执行的
shift()
。。。非常感谢你的帮助!!!谢谢你

您当前的实现存在一些问题:

  • 使用
    by=
    操作符进行per-
    CustomerID
    分组,不要尝试使用
    duplicated
    手动进行分组。这似乎类似于电子表格迫使我们思考的方式(因为它们通常不便于按组操作),即“如果此行的id与最后一行的id不同,请做一些不同的事情”。信任
    data.table
    by=
    操作符(或
    dplyr::group\u by
    或其他几个操作符)

  • 您没有通过
    fill=
    或其他机制在
    shift
    中说明新的“移位”元素。这将在列中引入一个
    NA
    ,请参见#3代码

  • 不幸的是,您的实现仅在某个时间点有效:即使我们更正分组并过度使用
    fifelse
    字段(我倾向于认为超过2-3个嵌套字段被过度使用),我们仍然会看到一个问题:

    dat[,lagstat:=shift(Status,type=“lag”),by=(CustomerID)]
    dat[,旅程状态:=
    fifelse(is.na(lagstat),状态,
    fifelse(lagstat==“A”和状态%c(“A”、“B”、“c”、“D”)中的状态,
    fifelse(lagstat==“B”和状态%c(“B”、“c”、“D”)中的状态,
    fifelse(lagstat==“C”和状态%C(“C”、“D”)中的状态,
    fifelse(lagstat==“D”和状态%c(“D”)中的状态,
    (()()),,
    by=(CustomerID)]
    dat
    #客户ID月状态lagstat旅程\ U状态
    #1:43210 1/1/18 A
    #2:43210 2/1/18 B A B
    #3:43210 3/1/18 A B
    #4:43210 4/1/18 B A B
    #5:43210 5/1/18 C
    #6:432106/1/18D
    #7:43210 7/1/18 B D
    #8:6543 1/1/19 C
    #9:65432/1/19D
    #10:6543 19年1月3日
    #11:6543 4/1/19 B A B失败
    #12:6543 5/1/19 C失败
    #13:6543 6/1/19 A C C失败
    
    虽然这看起来更好,但让我们看看它失败的地方:第11行。当它检查
    lagstat
    的值时,它会在该
    fifelse
    链开始之前查看该值,而不是在处理前一行的
    fifelse
    之后立即查看该值。也就是说,它基于相同的数据状态计算
    fifelse
    s中的所有向量。即使在每个
    fifelse
    中执行
    shift
    ,也不会看到前一个滞后值的值

  • 我想你需要的是一个累积函数。我将假设数据有明确的顺序性,
    max
    将起作用。作为记录,虽然我更喜欢使用
    cummax
    max(c(“A”,“B”))
    有效,但
    cummax(c(“A”,“B”)
    无效。因此,我们使用
    Reduce(…,acculate=TRUE)
    手动执行

    从新的
    dat
    数据开始

    dat[,行程状态:=减少(最大,状态,累计=真),
    by=(CustomerID)]
    dat
    #客户ID月状态旅程\ U状态
    #1:43210 1/1/18 A
    #2:43210 2/1/18 B
    #3:43210 3/1/18 A B
    #4:43210 4/1/18 B
    #5:43210 5/1/18 C
    #6:43210 6/1/18日
    #7:43210 7/1/18 B D
    #8:6543 1/1/19 C
    #9:65432/1/19D
    #10:6543公元3/1/19年
    #11:6543公元前4/1/19年
    #12:65435/1/19CD
    #13:6543公元6/1/19年
    
    即使
    max
    不起作用,如果您有一个自行开发的手动处理有序性的函数,那么您可以将其替换为
    max
    ,这应该可以起作用

    旁注:DanY建议,如果您的
    状态是真正的整数或数字,那么这将更简单:

    datnum[,旅程状态:=cummax(状态),by=(客户ID)]
    达特努姆
    #客户ID月状态旅程\ U状态
    #  1:      43210 1/1/18      1              1
    #  2:      43210 2/1/18      2              2
    #  3:      43210 3/1/18