(纵向数据)为每个 ID 创建具有最后一个值的新变量
(Longitudinal data) Create new variable with last value for each ID
我正在处理一个包含 ID、时间戳和值的纵向数据集。我想为每个人创建一个新变量,在每个人的行中保存该人的最后一个时间戳的值。例如,如果我的数据如下所示:
ID Time Value
1 1:20 1
1 2:43 2
1 1:56 3
2 1:10 4
2 1:05 5
我想这样创建一个新变量 Final_value:
ID Time Value Final_value
1 1:20 1 2
1 2:43 2 2
1 1:56 3 2
2 1:10 4 4
2 1:05 5 4
我更喜欢使用 R 的内置方法。也许有一种方法可以使用 "ave" 函数来做到这一点?
这里有一个 dplyr
的选项。按 'ID' 分组,将 'Time' 转换为时间 class with hm
from lubridate
,获取最大值(which.max
)和子集的索引'Value' 基于该索引
library(dplyr)
library(lubridate)
df1 %>%
group_by(ID) %>%
mutate(Final_value = Value[which.max(as.numeric(hm(Time)))])
# A tibble: 5 x 4
# Groups: ID [2]
# ID Time Value Final_value
# <int> <chr> <int> <int>
#1 1 1:20 1 2
#2 1 2:43 2 2
#3 1 1:56 3 2
#4 2 1:10 4 4
#5 2 1:05 5 4
或使用base R
df1$Final_value <- with(df1, Value[as.logical(ave(as.numeric(as.POSIXct(Time,
format = '%H:%M')),
ID, FUN = function(x) x== max(x)))][ID])
或者另一种选择是order
基于'Time'和'ID'的数据,然后用ave
[=得到last
值22=]
i1 <- with(df1, order(ID, as.POSIXct(TIme, format = '%H:%M')))
with(df1[i1,], ave(Value, ID, FUN = function(x) x[length(x)]))
数据
df1 <- structure(list(ID = c(1L, 1L, 1L, 2L, 2L), Time = c("1:20", "2:43",
"1:56", "1:10", "1:05"), Value = 1:5), class = "data.frame", row.names = c(NA,
-5L))
这是data.table
事情的方式
library( data.table )
#make your data (dt) a data.table
setDT( dt )
#set Time as a iTime
dt[, Time := as.ITime( Time )]
#get the value of the max Time, by ID
dt[, Final_value := , by = .( ID ) ]
#perform an update join, where you join
# the maximum Value by ID on dt itself
dt[ dt[dt[, .I[Time == max(Time)], by = ID]$V1],
Final_value := i.Value,
on = .(ID)]
# ID Time Value Final_value
# 1: 1 01:20:00 1 2
# 2: 1 02:43:00 2 2
# 3: 1 01:56:00 3 2
# 4: 2 01:10:00 4 4
# 5: 2 01:05:00 5 4
我正在处理一个包含 ID、时间戳和值的纵向数据集。我想为每个人创建一个新变量,在每个人的行中保存该人的最后一个时间戳的值。例如,如果我的数据如下所示:
ID Time Value
1 1:20 1
1 2:43 2
1 1:56 3
2 1:10 4
2 1:05 5
我想这样创建一个新变量 Final_value:
ID Time Value Final_value
1 1:20 1 2
1 2:43 2 2
1 1:56 3 2
2 1:10 4 4
2 1:05 5 4
我更喜欢使用 R 的内置方法。也许有一种方法可以使用 "ave" 函数来做到这一点?
这里有一个 dplyr
的选项。按 'ID' 分组,将 'Time' 转换为时间 class with hm
from lubridate
,获取最大值(which.max
)和子集的索引'Value' 基于该索引
library(dplyr)
library(lubridate)
df1 %>%
group_by(ID) %>%
mutate(Final_value = Value[which.max(as.numeric(hm(Time)))])
# A tibble: 5 x 4
# Groups: ID [2]
# ID Time Value Final_value
# <int> <chr> <int> <int>
#1 1 1:20 1 2
#2 1 2:43 2 2
#3 1 1:56 3 2
#4 2 1:10 4 4
#5 2 1:05 5 4
或使用base R
df1$Final_value <- with(df1, Value[as.logical(ave(as.numeric(as.POSIXct(Time,
format = '%H:%M')),
ID, FUN = function(x) x== max(x)))][ID])
或者另一种选择是order
基于'Time'和'ID'的数据,然后用ave
[=得到last
值22=]
i1 <- with(df1, order(ID, as.POSIXct(TIme, format = '%H:%M')))
with(df1[i1,], ave(Value, ID, FUN = function(x) x[length(x)]))
数据
df1 <- structure(list(ID = c(1L, 1L, 1L, 2L, 2L), Time = c("1:20", "2:43",
"1:56", "1:10", "1:05"), Value = 1:5), class = "data.frame", row.names = c(NA,
-5L))
这是data.table
事情的方式
library( data.table )
#make your data (dt) a data.table
setDT( dt )
#set Time as a iTime
dt[, Time := as.ITime( Time )]
#get the value of the max Time, by ID
dt[, Final_value := , by = .( ID ) ]
#perform an update join, where you join
# the maximum Value by ID on dt itself
dt[ dt[dt[, .I[Time == max(Time)], by = ID]$V1],
Final_value := i.Value,
on = .(ID)]
# ID Time Value Final_value
# 1: 1 01:20:00 1 2
# 2: 1 02:43:00 2 2
# 3: 1 01:56:00 3 2
# 4: 2 01:10:00 4 4
# 5: 2 01:05:00 5 4