R “嵌套”的问题;ifelse();通过“引用”引用上一行;shift();
我试图使用嵌套的ifelse()和shift()将各种业务逻辑应用于源数据集,但我的代码给出了我不理解的结果。问题陈述如下:我有一个包含“CustomerID”、“Month”和“Status”的客户数据集 我需要通过应用以下逻辑创建第三列“旅程状态”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(班次
#初始化每个客户的第一条记录。
示例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