【问题标题】:Creating a matrix based on time series at different locations in R基于R中不同位置的时间序列创建矩阵
【发布时间】:2023-03-08 20:01:01
【问题描述】:

我希望创建一个函数来创建一个矩阵,该矩阵基于多个唯一的个人 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),但 loc_lag 输出是 - 1、0、1、0、0 - 所以只显示新位置之间的动作.

【问题讨论】:

  • 也许您没有使用更新后的代码?这显示了 5 个动作:df2[ , lag_loc := shift(location2), by = individual2 ][location2 != lag_loc, dcast(.SD, lag_loc ~ location2, fill = 0, value.var = 'individual2', fun.aggregate = length)]
  • b1316 在这个数据集中
  • @MichaelChirico 我想我已经发现了问题,但不确定如何解决它。当该部分代码运行时,它会识别出五个更改。然而,在df2[ , row_change_id := rowid(individual2, location2)][] 期间发生了一些事情,当它转换/排名它们和之前使用的因素(站点编号)时,它们不会作为新动作出现。当您在 df2[ , row_change_id := rowid(individual2, location2)][] 运行后查看 df2 的输出时,您会看到 row_change_id 不是 1,而是应该是 2/3,就好像个人在同一个地方一样。
  • 再次,我不确定您是否使用更新的答案...我不再使用 rowid
  • 道歉。你说的对。非常感谢您的帮助。

标签: r matrix social-networking


【解决方案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 应用于origindestination 的相同组合内的所有行,即,对于每个 O-D 组合,输出中的每个单元格都应该是 length(individual),这应该很清楚,以查看此类个体的数量:

dcast(df_change, loc_lag ~ locations, fill = 0,
      value.var = 'individual', fun.aggregate = length)

【讨论】:

  • 非常感谢您的回答,它非常好,几乎就是我想要的。自始至终添加的信息令人惊叹。 2 来自代码中第 1 - 2 行的个体 1 和第 8 -9 行的个体 2 的移动:df[ , row_change_id := rowid(individual, locations)][]。在您的 sig_id 中,第 8 行和第 9 行不是 2,但第 9 行应该是 1。
  • @DFinch 确实我最初的回答是错误的,我以为我涵盖了我未能做到的情况。现已修复。
  • 这太棒了。我一直在查看我的数据,似乎还有其他问题。如果该位置已被使用,它似乎会将其从分组的其余部分中删除,即使个人可能会再次回到那里。我的意思是例如如果您将这些作为位置 ID (4, 5, 4, 1, 5, 4),然后个人正在穿过它们,它应该看起来像 - 1, 1, 1, 1, 1 - 就移动分数而言,但是我认为代码所做的是给出 - 1, 0, 1, 0, 0 - 作为输出。那有意义吗?感谢您的所有帮助。非常感谢。
  • @DFinch 我不确定我是否遵循,您能否在问题的示例中包含此内容?
猜你喜欢
  • 2015-03-24
  • 1970-01-01
  • 2014-09-19
  • 1970-01-01
  • 1970-01-01
  • 2020-11-24
  • 2021-07-15
  • 2017-10-18
  • 2020-06-12
相关资源
最近更新 更多