gpt4 book ai didi

r - 从数据框中的每个分组行中减去上一年的值

转载 作者:行者123 更新时间:2023-12-04 17:55:08 25 4
gpt4 key购买 nike

我正在尝试计算无意中汇总的数据的滞后差异(或实际增加)。数据中的每一年都包括上一年的值。可以使用以下代码创建示例数据集:

set.seed(1234)
x <- data.frame(id=1:5, value=sample(20:30, 5, replace=T), year=3)
y <- data.frame(id=1:5, value=sample(10:19, 5, replace=T), year=2)
z <- data.frame(id=1:5, value=sample(0:9, 5, replace=T), year=1)
(df <- rbind(x, y, z))

我可以使用 lapply() 的组合和 split()计算每个唯一 id 每年之间的差异,如下所示:
(diffs <- lapply(split(df, df$id), function(x){-diff(x$value)}))

但是,由于 diff() 的性质函数,第 1 年的值没有结果,这意味着在我展平 diffs 之后带有 Reduce() 的列表列表,我无法将实际的年度增长添加回数据框中,如下所示:
df$actual <- Reduce(c, diffs)  # flatten the list of lists

在此示例中,只有 10 个计算的差异或滞后,而数据框中有 15 行,因此 R 在尝试添加新列时抛出错误。

如何使用 (1) 第 1 年的值和 (2) 计算出的所有后续年份的差异/滞后来创建新的实际增长列?

这是我最终要寻找的输出。我的 diffs列表列表计算第 2 年和第 3 年的实际值就好了。
id value year actual
1 21 3 5
2 26 3 16
3 26 3 14
4 26 3 10
5 29 3 14
1 16 2 10
2 10 2 5
3 12 2 10
4 16 2 7
5 15 2 13
1 6 1 6
2 5 1 5
3 2 1 2
4 9 1 9
5 2 1 2

最佳答案

我认为这对你有用。当您遇到 diff 问题时,只需将 0 作为第一个数字来延长向量。

df <- df[order(df$id, df$year), ]
sdf <-split(df, df$id)
df$actual <- as.vector(sapply(seq_along(sdf), function(x) diff(c(0, sdf[[x]][,2]))))
df[order(as.numeric(rownames(df))),]

有很多方法可以做到这一点,但这种方法相当快并且使用基础。

这是使用聚合和通过以下方式解决此问题的第二种和第三种方法:

聚合:
df <- df[order(df$id, df$year), ]
diff2 <- function(x) diff(c(0, x))
df$actual <- c(unlist(t(aggregate(value~id, df, diff2)[, -1])))
df[order(as.numeric(rownames(df))),]

作者:
df <- df[order(df$id, df$year), ]
diff2 <- function(x) diff(c(0, x))
df$actual <- unlist(by(df$value, df$id, diff2))
df[order(as.numeric(rownames(df))),]

胶合板
df <- df[order(df$id, df$year), ]
df <- data.frame(temp=1:nrow(df), df)
library(plyr)
df <- ddply(df, .(id), transform, actual=diff2(value))
df[order(-df$year, df$temp),][, -1]

它为您提供以下最终产品:
> df[order(as.numeric(rownames(df))),]
id value year actual
1 1 21 3 5
2 2 26 3 16
3 3 26 3 14
4 4 26 3 10
5 5 29 3 14
6 1 16 2 10
7 2 10 2 5
8 3 12 2 10
9 4 16 2 7
10 5 15 2 13
11 1 6 1 6
12 2 5 1 5
13 3 2 1 2
14 4 9 1 9
15 5 2 1 2

编辑:避免循环

我可以建议避免循环并将我给你的东西变成一个函数(by 解决方案是我最容易使用的解决方案)并将其应用到你想要的两列。
set.seed(1234)  #make new data with another numeric column
x <- data.frame(id=1:5, value=sample(20:30, 5, replace=T), year=3)
y <- data.frame(id=1:5, value=sample(10:19, 5, replace=T), year=2)
z <- data.frame(id=1:5, value=sample(0:9, 5, replace=T), year=1)
df <- rbind(x, y, z)
df <- df.rep <- data.frame(df[, 1:2], new.var=df[, 2]+sample(1:5, nrow(df),
replace=T), year=df[, 3])


df <- df[order(df$id, df$year), ]
diff2 <- function(x) diff(c(0, x)) #function one
group.diff<- function(x) unlist(by(x, df$id, diff2)) #answer turned function
df <- data.frame(df, sapply(df[, 2:3], group.diff)) #apply group.diff to col 2:3
df[order(as.numeric(rownames(df))),] #reorder it

当然,除非您使用 transform,否则您必须重命名这些。如:
df <- df[order(df$id, df$year), ]
diff2 <- function(x) diff(c(0, x)) #function one
group.diff<- function(x) unlist(by(x, df$id, diff2)) #answer turned function
df <- transform(df, actual=group.diff(value), actual.new=group.diff(new.var))
df[order(as.numeric(rownames(df))),]

这将取决于您对多少变量执行此操作。

关于r - 从数据框中的每个分组行中减去上一年的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9552771/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com