如何跟踪r中数据的变化?

时间:2018-04-09 14:53:09

标签: r

我很难在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'); } datepackage_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,并且我将获得具有不同日期和位置的多个列。然后我可以过滤掉不相等的位置变化。但对我来说这似乎太复杂了。

感谢您的帮助!

1 个答案:

答案 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