创建新的 R 数据帧变量时使用前一行值
Using previous row values when creating new R dataframe variable
对于 R 数据框的问题,我非常感谢您的帮助。找不到类似的主题,如果已经存在请分享!
我有以下数据:
mydata <- data.frame(inflow=c(50,60,55,70,80),
outflow=c(70,80,70,65,65),
current=c(100,100,100,100,100))
我想创建一个新的专栏,其作用如下:
mutate(calc=pmax(lag(calc,default=current)+inflow-outflow,inflow))
这基本上创建了一个名为 calc 的新列,它在 a) calc 的前一行值加上该行的流入减去流出或 b) 该行的流入值的最大值之间进行选择。 pmax 是一个来自名为 rmpfr 的包的函数,它选择每行给定列的最大值。
所以我的结果将是:row1 = max(100+50-70, 50) 是 80,row2 = max(80+60-80,60) 是 60 等等。
主要问题是滞后函数不允许为您正在创建的同一列获取前一行的值,它必须是数据中已经存在的列。我想通过先创建计算列然后添加第二个计算步骤来分步进行,但无法完全解决。
最后,我知道使用 for 循环可能是一种解决方案,但想知道是否有其他方法?我的数据按额外的列分组,不确定 for 循环是否适用于分组数据行?
感谢您的帮助:)
也许 cummax 函数会有帮助
mutate(calc=pmax(cummax(current+inflow-outflow),inflow))
# I don't define the current column, as this is handled with the .init argument of accumulate2
mydata <- data.frame(
inflow=c(50,60,55,70,80),
outflow=c(70,80,70,65,65)
)
# define your recursive function
flow_function <- function(current, inflow, outflow){
pmax(inflow, inflow - outflow + current)
}
mydata %>%
mutate(result = accumulate2(inflow, outflow, flow_function, .init = 100)[-1] %>% unlist)
# inflow outflow result
# 1 50 70 80
# 2 60 80 60
# 3 55 70 55
# 4 70 65 70
# 5 80 65 85
详情
purrr::accumulate
系列函数旨在执行递归计算。
accumulate
可以处理从前一个值加上另一列的值的函数,而 accumulate2
允许第二个附加列。你的情况属于后者。
accumulate2
需要以下参数:
.x
- 计算的第一列。
.y
- 用于计算的第二列。
.f
- 递归应用的函数:这应该有三个参数,第一个是递归参数。
.init
-(可选)用作第一个参数的初始值。
因此在您的情况下,传递给 .f
的函数将是
# define your recursive function
flow_function <- function(current, inflow, outflow){
pmax(inflow, inflow - outflow + current)
}
我们首先测试它在 dplyr::mutate
之外产生的结果
# note I don't define the current column, as this is handled with the .init argument
mydata <- data.frame(
inflow=c(50,60,55,70,80),
outflow=c(70,80,70,65,65)
)
purrr::accumulate2(mydata$inflow, mydata$outflow, flow_function, .init = 100)
# returns
# [[1]]
# [1] 100
#
# [[2]]
# [1] 80
#
# [[3]]
# [1] 60
#
# [[4]]
# [1] 55
#
# [[5]]
# [1] 70
#
# [[6]]
# [1] 85
所以返回值有两点需要注意:
- 返回的对象是一个列表,所以我们要
unlist
返回一个向量。
- 该列表有 6 个条目,因为它包含初始值,我们要删除它。
最后两个步骤在顶部的完整示例中汇集在一起。
对于 R 数据框的问题,我非常感谢您的帮助。找不到类似的主题,如果已经存在请分享!
我有以下数据:
mydata <- data.frame(inflow=c(50,60,55,70,80),
outflow=c(70,80,70,65,65),
current=c(100,100,100,100,100))
我想创建一个新的专栏,其作用如下:
mutate(calc=pmax(lag(calc,default=current)+inflow-outflow,inflow))
这基本上创建了一个名为 calc 的新列,它在 a) calc 的前一行值加上该行的流入减去流出或 b) 该行的流入值的最大值之间进行选择。 pmax 是一个来自名为 rmpfr 的包的函数,它选择每行给定列的最大值。
所以我的结果将是:row1 = max(100+50-70, 50) 是 80,row2 = max(80+60-80,60) 是 60 等等。
主要问题是滞后函数不允许为您正在创建的同一列获取前一行的值,它必须是数据中已经存在的列。我想通过先创建计算列然后添加第二个计算步骤来分步进行,但无法完全解决。
最后,我知道使用 for 循环可能是一种解决方案,但想知道是否有其他方法?我的数据按额外的列分组,不确定 for 循环是否适用于分组数据行?
感谢您的帮助:)
也许 cummax 函数会有帮助
mutate(calc=pmax(cummax(current+inflow-outflow),inflow))
# I don't define the current column, as this is handled with the .init argument of accumulate2
mydata <- data.frame(
inflow=c(50,60,55,70,80),
outflow=c(70,80,70,65,65)
)
# define your recursive function
flow_function <- function(current, inflow, outflow){
pmax(inflow, inflow - outflow + current)
}
mydata %>%
mutate(result = accumulate2(inflow, outflow, flow_function, .init = 100)[-1] %>% unlist)
# inflow outflow result
# 1 50 70 80
# 2 60 80 60
# 3 55 70 55
# 4 70 65 70
# 5 80 65 85
详情
purrr::accumulate
系列函数旨在执行递归计算。
accumulate
可以处理从前一个值加上另一列的值的函数,而 accumulate2
允许第二个附加列。你的情况属于后者。
accumulate2
需要以下参数:
.x
- 计算的第一列。.y
- 用于计算的第二列。.f
- 递归应用的函数:这应该有三个参数,第一个是递归参数。.init
-(可选)用作第一个参数的初始值。
因此在您的情况下,传递给 .f
的函数将是
# define your recursive function
flow_function <- function(current, inflow, outflow){
pmax(inflow, inflow - outflow + current)
}
我们首先测试它在 dplyr::mutate
# note I don't define the current column, as this is handled with the .init argument
mydata <- data.frame(
inflow=c(50,60,55,70,80),
outflow=c(70,80,70,65,65)
)
purrr::accumulate2(mydata$inflow, mydata$outflow, flow_function, .init = 100)
# returns
# [[1]]
# [1] 100
#
# [[2]]
# [1] 80
#
# [[3]]
# [1] 60
#
# [[4]]
# [1] 55
#
# [[5]]
# [1] 70
#
# [[6]]
# [1] 85
所以返回值有两点需要注意:
- 返回的对象是一个列表,所以我们要
unlist
返回一个向量。 - 该列表有 6 个条目,因为它包含初始值,我们要删除它。
最后两个步骤在顶部的完整示例中汇集在一起。