根据 R 中不同位置的时间序列创建矩阵
Creating a matrix based on time series at different locations in R
我想创建一个函数来创建一个矩阵,该矩阵基于许多唯一的个人 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 - 所以只显示新地点之间的移动。
您可以使用 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]
将此 table 宽度重塑为 origin ~ destination
; fill = 0
表示任何未表示的 origin
->destination
组合将显示为 0(尤其是沿着对角线)。 value.var
在这里并不重要,但是 individual
非常直观,因为它具有解释——当我们重塑时,我们将 fun.aggregate
应用于 [= 的相同组合中的所有行24=] 和 destination
,即对于每个 O-D 组合,输出中的每个单元格应该是 length(individual)
,这应该很清楚地看到这些个体的数量:
dcast(df_change, loc_lag ~ locations, fill = 0,
value.var = 'individual', fun.aggregate = length)
我想创建一个函数来创建一个矩阵,该矩阵基于许多唯一的个人 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 - 所以只显示新地点之间的移动。
您可以使用 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]
将此 table 宽度重塑为 origin ~ destination
; fill = 0
表示任何未表示的 origin
->destination
组合将显示为 0(尤其是沿着对角线)。 value.var
在这里并不重要,但是 individual
非常直观,因为它具有解释——当我们重塑时,我们将 fun.aggregate
应用于 [= 的相同组合中的所有行24=] 和 destination
,即对于每个 O-D 组合,输出中的每个单元格应该是 length(individual)
,这应该很清楚地看到这些个体的数量:
dcast(df_change, loc_lag ~ locations, fill = 0,
value.var = 'individual', fun.aggregate = length)