根据时间序列在R中的不同位置创建矩阵

时间:2018-09-26 16:38:30

标签: r matrix social-networking

我希望创建一个函数来创建一个矩阵,该矩阵基于大量不同日期上的唯一ID到不同位置的移动。

从本质上讲,我希望统计一下个人在不同地点之间的移动次数。每次运动计数为1.,因为我只希望查看运动,所以第一个位置将不计算为1,但是第一个日期和第二个日期之间的运动将计算为1,如果个人呆在原地,则不会计算为运动。

一个示例数据框将是(除了我有n个人和n个位置):

individual <- c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3)
locations <- c("L1", "L2", "L2", "L2", "L3", "L2", "L1", "L1", "L2", "L2", "L3", "L3", "L3", "L3", "L1")
date <- c("12/04/2018", "13/04/2018", "14/04/2018", "15/04/2018", "16/04/2018", "12/04/2018", "13/04/2018", "14/04/2018", "15/04/2018", "16/04/2018", "12/04/2018", "13/04/2018", "14/04/2018", "15/04/2018", "16/04/2018")
df <- data.frame(individual, date, locations)
df$individual <- as.factor(df$individual)
df$date <- as.Date(df$date, format = "%d/%m/%Y")

我正在尝试创建类似于以下内容的输出:

B = matrix( 
  c(0, 1, 1, 2, 0, 0, 0, 1, 0), 
  nrow=3, ncol=3
)
colnames(B) = c("L1_moved_to", "L2_moved_to", "L3_moved_to")
rownames(B) = c("L1_moved_from", "L2_moved_from", "L3_moved_from")

我希望然后绘制该矩阵的图形,但是发现在R中创建初始矩阵很困难

编辑

在查看df_change_with_lag_drop_initial的输出时使用我的数据,我得到:

individual1 <- c("b1316", "b1316")
location1 <- c(5, 1)
loc_lag1    <- c(4, 5)
df1 <- data.frame(individual1, location1, loc_lag1)

但是,当您查看原始数据时,它看起来像这样:

individual2 <- c("b1316", "b1316", "b1316", "b1316", "b1316", "b1316")
location2 <- c(4, 5, 4, 1, 5, 4)
date2   <- c("07/01/2012", "18/02/2012", "04/01/2013", "03/01/2014", "07/01/2016", "18/02/2017")
df2 <- data.frame(individual2, date2, location2)
df2$individual2 <- as.factor(df2$individual2)
df2$date2 <- as.Date(df2$date2, format = "%d/%m/%Y")
df2$location2 <- as.factor(df2$location2)

所以正如我之前提到的,分数应该显示5个运动(1、1、1、1、1、1),但是loc_lag输出为-1、0、1、0、0-因此仅显示新位置之间的运动。

1 个答案:

答案 0 :(得分:1)

您可以使用data.table十分简洁地完成此操作,如下所示:

library(data.table)
setDT(df)

df[ , lag_loc := shift(locations), by = individual
    ][locations != lag_loc,
      dcast(.SD, lag_loc ~ locations, fill = 0,
            value.var = 'individual', fun.aggregate = length)]
#    loc_lag L1 L2 L3
# 1:      L1  0  2  0
# 2:      L2  1  0  1
# 3:      L3  1  0  0

分为以下几步:

加载data.table;将df转换为data.table

 library(data.table)
 setDT(df)

查找与locations的更改相对应的行:

df[ , lag_loc := shift(locations), by = individual][]
#    individual       date locations lag_loc
#  1:          1 2018-04-12        L1    <NA>
#  2:          1 2018-04-13        L2      L1
#  3:          1 2018-04-14        L2      L2
#  4:          1 2018-04-15        L2      L2
#  5:          1 2018-04-16        L3      L2
#  6:          2 2018-04-12        L2    <NA>
#  7:          2 2018-04-13        L1      L2
#  8:          2 2018-04-14        L1      L1
#  9:          2 2018-04-15        L2      L1
# 10:          2 2018-04-16        L2      L2
# 11:          3 2018-04-12        L3    <NA>
# 12:          3 2018-04-13        L3      L3
# 13:          3 2018-04-14        L3      L3
# 14:          3 2018-04-15        L3      L3

df的子集仅更改为与location对应的行:

df_change = df[locations != lag_loc]

将此表的宽度改成origin ~ destinationfill = 0表示未表示的任何origin-> destination组合将显示为0(尤其是沿对角线)。 value.var在这里并不重要,但是individual相当直观,因为它具有以下解释:-在整形时,我们将fun.aggregate应用于{{ 1}}和origin,即对于每个OD组合,输出中的每个单元格应为destination,应该清晰可见,以计算此类个体的数量:

length(individual)