繁体   English   中英

R中基于先前变量值将行追加到数据框的函数

[英]Function for Appending Rows to Data Frame Based on Previous Variable Values in R

我正在尝试创建一个函数,该函数允许我根据最前一行(紧接在上方)的变量将行附加到现有数据框中,并进行多次。

#Here's what I'm starting with 

Balance <- c(25000)
Pmt <- c(1500)
Interest <- c(.05)
DF <- data.frame(Balance,Pmt,Interest)
DF  
   Balance Pmt Interest
1   25000 100     0.05

例如,我想查看添加的下4行,其中新行的“余额”等于上一行的((Balance-Pmt)*(1 + Inerest)),而“ Pmt”和“兴趣”行保持不变。

# Manually
DF[2,1] <- (DF[1,1] - DF[1,2])*(1+DF[1,3])
DF[2,2] <- DF[1,2]
DF[2,3] <- DF[1,3]
D
  Balance  Pmt Interest
1   25000 1500     0.05
2   24675 1500     0.05

显然,我想重复此操作n次,而不必手动引用上一行。 我想要一个函数,它允许我按照相同的逻辑向数据帧中添加行多次。 任何帮助表示赞赏!

您可以设置数据帧时要牢记最终大小,而不是逐行构建数据帧,这将非常低效。 在此示例中,您知道将运行此过程三次,以总共四行结束。 首先创建该数据框,以使其余数据更加轻松快捷:

DF2 <- 'row.names<-'(DF[rep(1,4),], NULL)
DF2$Balance <- Reduce(function(x,y) (x - y)*(1+DF2[1,3]), DF2[-1,2], init=DF[1,1], acc=TRUE)
DF2
#    Balance  Pmt Interest
# 1 25000.00 1500     0.05
# 2 24675.00 1500     0.05
# 3 24333.75 1500     0.05
# 4 23975.44 1500     0.05

自学:如何减少工作量?

Reduce功能是一种高级功能,以一种独特的方式工作,需要实践来掌握。 它包含两个主要部分:1)具有两个参数的函数,以及2)单个向量*。 那是奇怪的部分。 它需要一个具有两个参数和一个向量的函数。 起初这没有意义。 它如何通过一个带有两个参数的函数的向量? 例:

#one vector
x <- c(2,3,4,5)

#function with two arguments
multiply <- function(a, b)  {a * b}

这是2到5的向量,是一个简单的函数,它接受两个数字并将它们相乘。 Reduce将接受这两个对象并执行以下操作:

Reduce(multiply, x) #<- this
#is the same as
ans1 <- multiply(2, 3) 
ans2 <- multiply(ans1, 4)
ans3 <- multiply(ans2, 5)

它经过向量c(2,3,4,5)并取了前两个部分(2和3)并在它们上调用了函数。 然后,用那个答案并带入x(4)的第三个元素来运行函数,然后用那个答案并与第四个元素(5)一起运行。


在您的示例中,我们使用它来进行首笔余额和付款:

#one vector
x <- c(25000, 1500, 1500, 1500)

#function with two arguments
f <- function(a,b) (a - b)*(1 + 0.05)

让我们看看它在内部做了什么:

Reduce(f, x) #what we did
#internally Reduce did this
ans1 <- (25000 - 1500) * (1 + 0.05)
ans2 <- (ans1 - 1500) * (1 + 0.05)
ans3 <- (ans2 - 1500) * (1 + 0.05)

这给了我们所需的过程。 那就是我们所做的想法。 为了完全完成我们的讨论,我们添加了两个额外的参数来帮助我们获得期望的结果。 accumulate=TRUEinit=DF[1,1] 第一个简单地告诉Reduce,我们想要每个连续的答案,而不仅仅是最后一个。 第二个告诉减少我们要开始的价值。 显示init

#Supply vector for function
x <- DF[-1,2]
x
[1] 1500 1500 1500

#We need the initial balance
#init=DF[1,1] does: 
[1] 25000 1500 1500 1500

Reduce也可以列出一个列表,但是我们应该首先实现向量精通,然后介绍列表方法。

使用tvm:金钱的时间价值函数包:

library(tvm)

n <- 5
rem(cf = rep(1500, n), amt = 25000, r = 0.05)
# [1] 24750.00 24487.50 24211.88 23922.47 23618.59

创建数据集:

    Balance <- c(25000)
    Pmt <- c(1500)
    Interest <- c(.05)
    DF <- data.frame(Balance,Pmt,Interest)
    DF
1   25000 100     0.05

然后使用该函数说n = 10次:

> for(i in 2:10){
+   DF[i,1] <- (DF[i-1,1] - DF[i-1,2])*(1+DF[i-1,3])
+   DF[i,2] <- DF[i-1,2]
+   DF[i,3] <- DF[i-1,3]
+ }
> DF
    Balance  Pmt Interest
# 1  25000.00 1500     0.05
# 2  24675.00 1500     0.05
# 3  24333.75 1500     0.05
# 4  23975.44 1500     0.05
# 5  23599.21 1500     0.05
# 6  23204.17 1500     0.05
# 7  22789.38 1500     0.05
# 8  22353.85 1500     0.05
# 9  21896.54 1500     0.05
# 10 21416.37 1500     0.05

您可以将100或1000替换为10,具体取决于要运行此功能的次数。

您可以使用此功能

add_function <- function(n) invisible(replicate(n,{DF <<- rbind(DF,DF[nrow(DF),],make.row.names = F);DF[nrow(DF),1] <<- (DF[nrow(DF)-1,1]-DF[nrow(DF)-1,2])*(1+DF[nrow(DF)-1,3])}))

只需提供n的值

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM