我很难在r。
中找到跟踪问题的解决方案我有一个每日数据框,其中包含表示某个包位于某处的行。我在三列中有void strRet(std::string& out) {
// this just speeds it up, since we know the size in advance
out.reserve(1500);
// this is in case the string wasn't already empty
out.clear();
// and this actually does the work
std::fill_n(std::back_inserter(out), 1500, 'a');
}
,date
和package_id
。 Location_id是一个数字变量。
可能会发生许多天过去而location_id
没有变化。但是,我想创建一个新的数据框,我可以在其中跟踪location_id的变化。
让我们假设发生以下观察:
location_id
我想要生成的新对象应该包括package_id,“old”location_id,“last”123 location_id的日期,“new”location_id,以及“first”436 location_id的日期。
在示例中,它应该是这样的:
packake_id location_id date_id
PACK001 123 2018-04-02
PACK001 123 2018-04-03
PACK001 436 2018-04-04
我的第一个想法是通过package_id将所有数据帧组合成一个df,并且我将获得具有不同日期和位置的多个列。然后我可以过滤掉不相等的位置变化。但对我来说这似乎太复杂了。
感谢您的帮助!
答案 0 :(得分:1)
这是一种自连接策略,它使用移位的seq-indicator作为连接标准。
dta <- read.table(text="packake_id location_id date_id
PACK001 123 2018-04-02
PACK001 123 2018-04-03
PACK001 436 2018-04-04", header=TRUE,
colClasses=c("character", "character", "Date")
dta$dupes <- with(dta, duplicated( paste(packake_id, location_id,sep="_"),
fromLast=TRUE) )
dta2 <- dta[!dts$dupes, ] # removes non-changing pkg-locations
dta2$pack_seq <- as.numeric(ave(dta2$location_id, dta2$packake_id, FUN= seq_along))
dta2$pack_seq_next <- dta2$pack_seq -1 # the next loc now has same as prior loc
显然需要“清理”这个结果:
merge( dta2, dta2, by.x='pack_seq', by.y='pack_seq_next')
pack_seq packake_id.x location_id.x date_id.x dupes.x pack_seq_next packake_id.y
1 1 PACK001 123 2018-04-03 FALSE 0 PACK001
location_id.y date_id.y dupes.y pack_seq
1 436 2018-04-04 FALSE 2
清理,但将重命名留给您:
dta_shifts <- merge( dta2, dta2, by.x='pack_seq', by.y='pack_seq_next')
Warning message:
In merge.data.frame(dta2, dta2, by.x = "pack_seq", by.y = "pack_seq_next") :
column name ‘pack_seq’ is duplicated in the result
dta_shifts <- dta_shifts [, c('packake_id.x', 'date_id.x', 'location_id.x', 'date_id.y' , 'location_id.y')]
#--------
> dta_shifts
packake_id.x date_id.x location_id.x date_id.y location_id.y
1 PACK001 2018-04-03 123 2018-04-04 436
如果您添加了一个更大的示例,我会在“packake_id”中包含执行此操作所需的代码,但我认为不应该很难确定需要其他合并标准的位置。复制删除步骤已具有该功能。
这里有一些data.table代码使用@ Frank的rleid
建议使用更大的数据示例::
dta <- read.table(text="packake_id location_id date_id
PACK001 123 2018-04-02
PACK001 123 2018-04-03
PACK001 436 2018-04-04
PACK001 123 2018-04-02
PACK001 123 2018-04-03
PACK001 436 2018-04-04", header=TRUE, colClasses=c("character", "character", "Date"))
with(dta, rleid(packake_id,location_id))
[1] 1 1 2 3 3 4
setDT(dta)
dta[ , seq_id_loc := rleid(packake_id,location_id)]
dta[ !duplicated(seq_id_loc, fromLast=TRUE), ]
#------------
packake_id location_id date_id seq_id_loc
1: PACK001 123 2018-04-03 1
2: PACK001 436 2018-04-04 2
3: PACK001 123 2018-04-03 3
4: PACK001 436 2018-04-04 4
merge( dta2, dta2, by.x='seq_id_loc', by.y='pack_seq_next')
seq_id_loc packake_id.x location_id.x date_id.x pack_seq_next packake_id.y location_id.y
1: 1 PACK001 123 2018-04-03 0 PACK001 436
2: 2 PACK001 436 2018-04-04 1 PACK001 123
3: 3 PACK001 123 2018-04-03 2 PACK001 436
date_id.y seq_id_loc
1: 2018-04-04 2
2: 2018-04-03 3
3: 2018-04-04 4
dta3 <- merge( dta2, dta2, by.x='seq_id_loc', by.y='pack_seq_next')
dta3[ , list(packake_id.x, date_id.x, location_id.x, date_id.y , location_id.y)]
#-----------
packake_id.x date_id.x location_id.x date_id.y location_id.y
1: PACK001 2018-04-03 123 2018-04-04 436
2: PACK001 2018-04-04 436 2018-04-03 123
3: PACK001 2018-04-03 123 2018-04-04 436