我有以下格式的数据集:
person surveyDate value
a 2006 35
a 2009 44
b 2005 24
b 2007 38
c 2006 51
c 2007 52
c 2009 49
...我希望将其重塑为以下内容:
person dateDiff valueDiff
a 3 9
b 2 14
c 3 -2
...其中dateDiff是每个人最早和最新的surveyDate之间的差异,而valueDiff是每个人的最早和最新值之间的差异。请注意,有些人的调查比其他人更多,调查之间的时间也各不相同。
我一直在尝试使用data.table
(以及melt
/ dcast
),但尝试使用:=
j
分配新的列值让我完全难过。其他方法是受欢迎的。速度并不是一个大问题,因为数据集并不是很大。
答案 0 :(得分:6)
你可以做到
DT[, .SD[.N] - .SD[1], by = person]
# person surveyDate value
# 1: a 3 9
# 2: b 2 14
# 3: c 3 -2
如果一个组只有.N==1
个观察值,那么差异将显示为零。
或者,......
DT[, lapply(.SD, function(x) x[.N]-x[1]), by = person]
OP报告的速度要快得多。
答案 1 :(得分:0)
我在dplyr中的总结还不是很棒,但这里的答案很笨拙:
library(dplyr)
library(magrittr)
person <- c('a', 'a', 'b', 'b', 'c', 'c', 'c')
surveyDate <- c(2006, 2009, 2005, 2007, 2006, 2007, 2009)
value <- c(35, 44, 24, 38, 51, 52, 49)
df <- data.frame(person, surveyDate, value)
value_diff <- function(surveyDate, value) {
group_df <- data.frame(surveyDate, value)
earliest_value <- group_df %>%
arrange(surveyDate) %>%
slice(1) %>%
extract2(2)
latest_value <- group_df %>%
arrange(desc(surveyDate)) %>%
slice(1) %>%
extract2(2)
diff <- latest_value - earliest_value
}
df %>%
group_by(person) %>%
summarise(dateDiff = max(surveyDate) -min(surveyDate),
valueDiff = value_diff(surveyDate, value))