在R中创建动态函数

时间:2016-02-26 05:08:16

标签: r function

我有一个包含7列的数据框。 3列产品,原价和新价格是不言自明的。然后,Q1-Q4是4个季度的平均预测价格。

您将在这些列中看到的是代码,例如DN1,DG1,DN2等。这些代码具有与它们相关的值,但这些值与此练习无关,即它们可以是任何值。

对于Q1-Q4,使用例如公式计算每个单元值。 Q1中产品A的预计价格= DN1 + 1。因此,如果DN1 = 3,则预测价格为3 + 1 = 4.遵循类似的逻辑,所有产品的Q1-Q4中的每个值都是根据公式计算的。

我如何编辑我的功能,使其更具动态性/效率,如果公式发生变化,我可以轻松地进行更改,例如:如果Q2中产品D的预计价格公式发生变化,我应该能够轻松地进行更改,而无需修改代码。

我希望也许可以使用看起来像这样的excel / csv:

Cell         Formula    Period
Value[1]     =DN1+1      Q1
Value[2]     =DK1        Q2
Value[3]     =DK1        Q3
Value[4]     =DK1        Q4
Value[5]     =DN2+3 (this value e.g. changed from DN2)

我需要做的就是,在excel文件的相应单元格中更改公式,并通过函数传递csv / excel以获得输出。

我的数据框的可重现代码:

    Q1<-c("=DN1+1","=DN2+3","=DN3*4","=DN4-1","=DN1 + DN2 + DN3 + DN4") 
    Q2<-c("=DK1", "=DK2","=DN3+DK3","=DN4+DL3- DM1 * ( DM2 + ((-DJ7-DK3) / S20+ S22) + S223 + Y446 / ZQ282 - W223)","=DG1 + DG2 + DG3 + DG4")
    Q3<-c("=DK1","=DK2","=DG3 (-1 qtr) +DK3","=DG4(-1 qtr)+DL3- DM1 * ( DM2 + ((-DJ7-DK3) / S20+ S22) + S223 + Y446 / ZQ282 - W223)","=DG1 + DG2 + DG3 + DG4")
    Q4<-c("=DK1","=DK2","DG3 (-1 qtr) +DK3","=DG4(-1 qtr)+DL3- DM1 * ( DM2 + ((-DJ7-DK3) / S20+ S22) + S223 + Y446 / ZQ282 - W223)","DG1 + DG2 + DG3 + DG4")
    D1<-data.frame(Q1,Q2,Q3,Q4)
    D1$Product<-c("A","B","C","D","Total")
    D1$Original_Price<-c("DN1","DN2","DN3","DN4","DN7")
    D1$New_Price<-c("DG1","DG2","DG3","DG4","DG7")
    D1<-D1[,c(5,6,7,1,2,3,4)]

功能的可重现代码:目前,公式都是硬编码的。此函数将数据帧作为输入/参数,其中包含两列1.)代码列,例如DN1,DN2等.2。)与代码相关的值的列,例如22(DN1的值),48(DN2的值)等等。

function_1<-function(dta)
{
Product <- c("A","A","A","A","B","B","B","B","C","C","C","C","D","D","D","D","Total","Total","Total","Total")
Original_Price <- c("DN1","DN1","DN1","DN1","DN2","DN2","DN2","DN2","DN3","DN3","DN3","DN3","DN4","DN4","DN4","DN4","DN7","DN7","DN7","DN7")
New_Price <- c("DG1","DG1","DG1","DG1","DG2","DG2","DG2","DG2","DG3","DG3","DG3","DG3","DG4","DG4","DG4","DG4","DG7","DG7","DG7","DG7")
Period <- c("Q1","Q2","Q3","Q4","Q1","Q2","Q3","Q4","Q1","Q2","Q3","Q4","Q1","Q2","Q3","Q4","Q1","Q2","Q3","Q4")
Value <- c("n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a","n/a")
for (i in c (1:nrow(dta))) {
    assign(as.character(dta[i,1]), dta[i,2])
    print(dta[i,1])
    print ("_")
    print(dta[i,2])
}

Value[1] <- DN1+1
Value[2] <- DK1
Value[3] <- DK1
Value[4] <- DK1
Value[5] <- DN2   
Value[6] <- DK2
Value[7] <- DK2
Value[8] <- DK2
Value[9] <- DN3
Value[10] <- DN3 + DK3
Value[11] <- as.numeric(Value[10]) + DK3
Value[12] <- as.numeric(Value[11]) + DK3
Value[13] <- DN4
Value[14] <- DN4+DL3- DM1 * ( DM2 + ((-DJ7-DK3) / S20+ S22) + S223 + Y446 / ZQ282 - W223)
Value[15] <- as.numeric(Value[14]) + DL3 - DM1 * ( DM2 + ((0 -DJ7-DK3) / S20 + S22) + S223 + Y446 / ZQ282 - W223)
Value[16] <- as.numeric(Value[15]) + DL3 - DM1 * ( DM2 + ((0 -DJ7-DK3) / S20 + S22) + S223 + Y446 / ZQ282 - W223)
Value[17] <- DN1 + DN2 + DN3 + DN4 
Value[18] <- as.numeric(Value[2]) + as.numeric(Value[6]) + as.numeric(Value[10]) + as.numeric(Value[14]) 
Value[19] <- as.numeric(Value[3]) + as.numeric(Value[7]) + as.numeric(Value[11]) + as.numeric(Value[15]) 
Value[20] <- as.numeric(Value[4]) + as.numeric(Value[8]) + as.numeric(Value[12]) + as.numeric(Value[16])
output <- data.frame(Product,Original_Price,New_Price,Period,Value)
 }

更新: 如何修改代码以将硬编码引用替换为上一季度值,例如Value[11] <- as.numeric(Value[10]) + DK3

我假设这个函数的编码将带有后缀,但数据是按季度接收的,这意味着相同的单元格代码将重复4次(每季度一次),即

Code Value Period
DN1  200    Q1
DN1  300    Q2
DN1  400    Q3
DN1  500    Q4

所以我的功能会失败,因为它不会找到正确的值。

1 个答案:

答案 0 :(得分:1)

你在这里尝试做什么并不完全清楚,但这就是我理解它的方式。你有一张表,其中每个单元格的内容是根据特定列计算的。您希望能够更新公式并重新计算表中的值,而无需对所有内容进行硬编码。

我的解决方案是编写一个函数,在其中提供要更新的表和一个表,其中每个单元格是您要使用的公式。必须将公式记为字符。然后,您可以使用layoutName来完成这项工作。

让我们试试:

init

一些解释......函数并不复杂,但基本上我们采用公式数据框,我们评估每个单元格中的每个函数并创建一个新的数据框架。这个新数据框看起来很糟糕,因为它缺少列名和其他类型的信息。因此,我们只需检查哪些值已更新,然后覆盖这些值。

通过重写函数,你可以使它适合你自己的问题。

编辑:向量的快速示例,其中任何元素可能依赖于前面的元素......

on('init')