在编写需要for()和嵌套lapply循环的函数时保留变量?

时间:2017-03-03 19:08:55

标签: r

我有以下递归函数:

 new.trend <- function(MergedData)
    {
      sig <- c(2,4,6,8,9,11,12,13,14,15,16,17,18,19,20,21,24)
      ret <- as.list(rep(NA,length(sig))) 

      for (i in sig) { #Calculates output variables based on active signals
        x <- MergedData[[i]]
        x <- xts(x[,-1], order.by=x[,1])
        dev20 <- (x[,4]-x[,5])/x[,4]*100
        dev50 <- (x[,4]-x[,6])/x[,4]*100
        ret <- lapply(ret, function(x) merge(merge(tail(dev20, n=1L), tail(dev50, n=1L), tail(RSI, n=1L))))
      }
      na.omit(do.call(merge, ret))
    }
    print(new.trend(MergedData))

Sig是递归计算的,但为了帖子长度,我只是插入sig的计算值。

我遇到了麻烦,因为上面的代码只返回最后一组索引

[[1]]
           INR.LOW.1 INR.LOW.1.1      EMA
2017-02-22 -1585.909   -1584.359 31.86353

但我希望它能够回归:

$JPY
           JPY.LOW.1 JPY.LOW.1.1      EMA
2017-02-22 -1585.909   -1584.359 31.86353

$CHF
           CHF.LOW.1 CHF.LOW.1.1      EMA
2017-02-22 -1585.909   -1584.359 31.86353

等等。输入附在此处

 structure(list(EUR = structure(list(EUR.DATE = structure(1409202000, class = c("POSIXct", 
"POSIXt"), tzone = ""), EUR.HIGH = 1.3221, EUR.LOW = 1.316, EUR.OPEN = 1.3193, 
    EUR.CLOSE = 1.3182, EUR.20D = 1.3323, EUR.50D = 1.3465), .Names = c("EUR.DATE", 
"EUR.HIGH", "EUR.LOW", "EUR.OPEN", "EUR.CLOSE", "EUR.20D", "EUR.50D"
), row.names = 651L, class = "data.frame"), JPY = structure(list(
    JPY.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), JPY.HIGH = 103.92, JPY.LOW = 103.56, JPY.OPEN = 103.88, 
    JPY.CLOSE = 103.72, JPY.20D = 102.92, JPY.50D = 102.22), .Names = c("JPY.DATE", 
"JPY.HIGH", "JPY.LOW", "JPY.OPEN", "JPY.CLOSE", "JPY.20D", "JPY.50D"
), row.names = 651L, class = "data.frame"), GBP = structure(list(
    GBP.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), GBP.HIGH = 1.6614, GBP.LOW = 1.6567, GBP.OPEN = 1.6576, 
    GBP.CLOSE = 1.6586, GBP.20D = 1.6703, GBP.50D = 1.6919), .Names = c("GBP.DATE", 
"GBP.HIGH", "GBP.LOW", "GBP.OPEN", "GBP.CLOSE", "GBP.20D", "GBP.50D"
), row.names = 651L, class = "data.frame"), CHF = structure(list(
    CHF.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), CHF.HIGH = 0.9162, CHF.LOW = 0.9126, CHF.HIGH.1 = 0.9148, 
    CHF.OPEN = 0.9151, CHF.CLOSE = 0.9096, CHF50D = 0.9017), .Names = c("CHF.DATE", 
"CHF.HIGH", "CHF.LOW", "CHF.HIGH.1", "CHF.OPEN", "CHF.CLOSE", 
"CHF50D"), row.names = 651L, class = "data.frame"), AUD = structure(list(
    AUD.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), AUD.HIGH = 0.9374, AUD.LOW = 0.9332, AUD.OPEN = 0.9337, 
    AUD.CLOSE = 0.9357, AUD.20D = 0.9308, AUD.50D = 0.9359), .Names = c("AUD.DATE", 
"AUD.HIGH", "AUD.LOW", "AUD.OPEN", "AUD.CLOSE", "AUD.20D", "AUD.50D"
), row.names = 651L, class = "data.frame"), CAD = structure(list(
    CAD.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), CAD.HIGH = 1.0869, CAD.LOW = 1.0837, CAD.OPEN = 1.0865, 
    CAD.CLOSE = 1.0861, CAD.20D = 1.0925, CAD.50D = 1.0808), .Names = c("CAD.DATE", 
"CAD.HIGH", "CAD.LOW", "CAD.OPEN", "CAD.CLOSE", "CAD.20D", "CAD.50D"
), row.names = 651L, class = "data.frame"), NZD = structure(list(
    NZD.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), NZD.HIGH = 0.8408, NZD.LOW = 0.8364, NZD.OPEN = 0.8374, 
    NZD.CLOSE = 0.8383, NZD.20D = 0.8439, NZD.50D = 0.8596), .Names = c("NZD.DATE", 
"NZD.HIGH", "NZD.LOW", "NZD.OPEN", "NZD.CLOSE", "NZD.20D", "NZD.50D"
), row.names = 651L, class = "data.frame"), SEK = structure(list(
    SEK.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), SEK.HIGH = 6.9859, SEK.LOW = 6.9279, SEK.CLOSE = 6.9495, 
    SEK.OPEN = 6.9717, SEK.20D = 6.8953, SEK.50D = 6.8358), .Names = c("SEK.DATE", 
"SEK.HIGH", "SEK.LOW", "SEK.CLOSE", "SEK.OPEN", "SEK.20D", "SEK.50D"
), row.names = 651L, class = "data.frame"), NOK = structure(list(
    NOK.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), NOK.HIGH = 6.1938, NOK.LOW = 6.166, NOK.OPEN = 6.1804, 
    NOK.CLOSE = 6.1795, NOK.20D = 7.5975, NOK.50D = 6.1876), .Names = c("NOK.DATE", 
"NOK.HIGH", "NOK.LOW", "NOK.OPEN", "NOK.CLOSE", "NOK.20D", "NOK.50D"
), row.names = 651L, class = "data.frame"), CZK = structure(list(
    CZK.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), CZK.HIGH = 21.1434, CZK.LOW = 20.9375, CZK.OPEN = 20.9924, 
    CZK.CLOSE = 21.11, CZK.20D = 20.9924, CZK.50D = 21.11), .Names = c("CZK.DATE", 
"CZK.HIGH", "CZK.LOW", "CZK.OPEN", "CZK.CLOSE", "CZK.20D", "CZK.50D"
), row.names = 651L, class = "data.frame"), HUF = structure(list(
    HUF.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), HUF.HIGH = 240.3, HUF.LOW = 236.56, HUF.HIGH.1 = 237, 
    HUF.LOW.1 = 239.06, HUF.20D = 235.57, HUF.50D = 231.14), .Names = c("HUF.DATE", 
"HUF.HIGH", "HUF.LOW", "HUF.HIGH.1", "HUF.LOW.1", "HUF.20D", 
"HUF.50D"), row.names = 651L, class = "data.frame"), ILS = structure(list(
    ILS.DATE = structure(1408597200, class = c("POSIXct", "POSIXt"
    ), tzone = ""), ILS.HIGH = 3.5505, ILS.LOW = 3.5185, ILS.HIGH.1 = 3.545, 
    ILS.LOW.1 = 3.526, ILS.20D = 3.4654, ILS.50D = 3.4442), .Names = c("ILS.DATE", 
"ILS.HIGH", "ILS.LOW", "ILS.HIGH.1", "ILS.LOW.1", "ILS.20D", 
"ILS.50D"), row.names = 651L, class = "data.frame"), PLN = structure(list(
    PLN.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), PLN.HIGH = 3.2101, PLN.LOW = 3.1767, PLN.HIGH.1 = 3.1831, 
    PLN.LOW.1 = 3.2036, PLN.20D = 3.1475, PLN.50D = 3.0943), .Names = c("PLN.DATE", 
"PLN.HIGH", "PLN.LOW", "PLN.HIGH.1", "PLN.LOW.1", "PLN.20D", 
"PLN.50D"), row.names = 651L, class = "data.frame"), RUB = structure(list(
    RUB.DATE = structure(1406178000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), RUB.HIGH = 35.1463, RUB.LOW = 34.9402, RUB.HIGH.1 = 35.0165, 
    RUB.LOW.1 = 35.0413, RUB.20D = 34.4608, RUB.50D = 34.4596), .Names = c("RUB.DATE", 
"RUB.HIGH", "RUB.LOW", "RUB.HIGH.1", "RUB.LOW.1", "RUB.20D", 
"RUB.50D"), row.names = 651L, class = "data.frame"), TRY = structure(list(
    TRY.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), TRY.HIGH = 2.1727, TRY.LOW = 2.1536, TRY.LOW.1 = 2.154, 
    TRY.HIGH.1 = 2.1581, TRY.20D = 2.1599, TRY.50D = 2.1372), .Names = c("TRY.DATE", 
"TRY.HIGH", "TRY.LOW", "TRY.LOW.1", "TRY.HIGH.1", "TRY.20D", 
"TRY.50D"), row.names = 651L, class = "data.frame"), ZAR = structure(list(
    ZAR.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), ZAR.HIGH = 10.6868, ZAR.LOW = 10.6034, ZAR.HIGH.1 = 10.6129, 
    ZAR.LOW.1 = 10.6511, ZAR.20D = 10.6612, ZAR.50D = 10.6554), .Names = c("ZAR.DATE", 
"ZAR.HIGH", "ZAR.LOW", "ZAR.HIGH.1", "ZAR.LOW.1", "ZAR.20D", 
"ZAR.50D"), row.names = 651L, class = "data.frame"), BRL = structure(list(
    BRL.DATE = structure(1406523600, class = c("POSIXct", "POSIXt"
    ), tzone = ""), BRL.HIGH = 2.2348, BRL.LOW = 2.2222, BRL.HIGH.1 = 2.2294, 
    BRL.LOW.1 = 2.2225, BRL.20D = 2.2209, BRL.50D = 2.2271), .Names = c("BRL.DATE", 
"BRL.HIGH", "BRL.LOW", "BRL.HIGH.1", "BRL.LOW.1", "BRL.20D", 
"BRL.50D"), row.names = 651L, class = "data.frame"), CLP = structure(list(
    CLP.DATE = structure(1405573200, class = c("POSIXct", "POSIXt"
    ), tzone = ""), CLP.HIGH = 565.75, CLP.LOW = 557.75, CLP.HIGH.1 = 559.51, 
    CLP.LOW.1 = 564.54, CLP.20D = 553.43, CLP.50D = 553.42), .Names = c("CLP.DATE", 
"CLP.HIGH", "CLP.LOW", "CLP.HIGH.1", "CLP.LOW.1", "CLP.20D", 
"CLP.50D"), row.names = 651L, class = "data.frame"), COP = structure(list(
    COP.DATE = structure(1405918800, class = c("POSIXct", "POSIXt"
    ), tzone = ""), COP.HIGH = 1868.5, COP.LOW = 1866.7, COP.OPEN = 1866.7, 
    COP.CLOSE = 1868.5, COP.20D = 1867.79, COP.50D = 1889.27), .Names = c("COP.DATE", 
"COP.HIGH", "COP.LOW", "COP.OPEN", "COP.CLOSE", "COP.20D", "COP.50D"
), row.names = 651L, class = "data.frame"), MXN = structure(list(
    MXN.DATE = structure(1409202000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), MXN.HIGH = 13.1309, MXN.LOW = 13.0689, MXN.HIGH.1 = 13.0844, 
    MXN.LOW.1 = 13.0856, MXN.20D = 13.1462, MXN.50D = 13.0548), .Names = c("MXN.DATE", 
"MXN.HIGH", "MXN.LOW", "MXN.HIGH.1", "MXN.LOW.1", "MXN.20D", 
"MXN.50D"), row.names = 651L, class = "data.frame"), PEN = structure(list(
    PEN.DATE = structure(1406696400, class = c("POSIXct", "POSIXt"
    ), tzone = ""), PEN.HIGH = 2.7935, PEN.LOW = 2.7866, PEN.LOW.1 = 2.7873, 
    PEN.HIGH.1 = 2.7895, PEN.20D = 2.7846, PEN.50D = 2.7885), .Names = c("PEN.DATE", 
"PEN.HIGH", "PEN.LOW", "PEN.LOW.1", "PEN.HIGH.1", "PEN.20D", 
"PEN.50D"), row.names = 651L, class = "data.frame"), CNY = structure(list(
    CNY.DATE = structure(1403758800, class = c("POSIXct", "POSIXt"
    ), tzone = ""), CNY.HIGH = 6.2337, CNY.LOW = 6.2243, CNY.OPEN = 6.229, 
    CNY.CLOSE = 6.2248, CNY.20D = 6.2336, CNY.50D = 6.2355), .Names = c("CNY.DATE", 
"CNY.HIGH", "CNY.LOW", "CNY.OPEN", "CNY.CLOSE", "CNY.20D", "CNY.50D"
), row.names = 651L, class = "data.frame"), IDR = structure(list(
    IDR.DATE = structure(1404709200, class = c("POSIXct", "POSIXt"
    ), tzone = ""), IDR.HIGH = 11870, IDR.LOW = 11683, IDR.HIGH.1 = 11829, 
    IDR.LOW.1 = 11710, IDR.20D = 11906, IDR.50D = 11722), .Names = c("IDR.DATE", 
"IDR.HIGH", "IDR.LOW", "IDR.HIGH.1", "IDR.LOW.1", "IDR.20D", 
"IDR.50D"), row.names = 651L, class = "data.frame"), INR = structure(list(
    INR.DATE = structure(1402462800, class = c("POSIXct", "POSIXt"
    ), tzone = ""), INR.HIGH = 59.36, INR.LOW = 59.325, INR.HIGH.1 = 59.0025, 
    INR.LOW.1 = 59.7634, INR.20D = 1041.23, INR.50D = 1037), .Names = c("INR.DATE", 
"INR.HIGH", "INR.LOW", "INR.HIGH.1", "INR.LOW.1", "INR.20D", 
"INR.50D"), row.names = 651L, class = "data.frame"), KRW = structure(list(
    KRW.DATE = structure(1407474000, class = c("POSIXct", "POSIXt"
    ), tzone = ""), KRW.HIGH = 1028.73, KRW.LOW = 1021.58, KRW.HIGH.1 = 3.1748, 
    KRW.LOW.1 = 3.1745, KRW.20D = 3.1805, KRW.50D = 3.2027), .Names = c("KRW.DATE", 
"KRW.HIGH", "KRW.LOW", "KRW.HIGH.1", "KRW.LOW.1", "KRW.20D", 
"KRW.50D"), row.names = 651L, class = "data.frame")), .Names = c("EUR", 
"JPY", "GBP", "CHF", "AUD", "CAD", "NZD", "SEK", "NOK", "CZK", 
"HUF", "ILS", "PLN", "RUB", "TRY", "ZAR", "BRL", "CLP", "COP", 
"MXN", "PEN", "CNY", "IDR", "INR", "KRW"))

1 个答案:

答案 0 :(得分:0)

首先:您的示例不起作用,因为您没有提供RSI。所以,我将假设RSI <- dev50

你的问题在这一行:

ret <- lapply(ret, function(x) merge(merge(tail(dev20, n=1L), tail(dev50, n=1L), tail(RSI, n=1L))))

这是一个for循环。因此,每次循环都会覆盖它。 你在这里有两倍merge,这是没用的。

您要做的是拥有一个lapply而不是looplapply

new.trend <- function(MergedData) {
  sig <- c(2, 4, 6, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 24)

  ret <- lapply(sig, function(i) {
    x <- MergedData[[i]]
    x <- xts(x[, -1], order.by = x[, 1])
    dev20 <- (x[, 4] - x[, 5]) / x[, 4] * 100
    dev50 <- (x[, 4] - x[, 6]) / x[, 4] * 100
    RSI <- dev50
    merge(last(dev20), last(dev50), last(RSI))

  })
  ret
}

这将返回您想要的内容:

new.trend(MergedData)

[[1]]
                    JPY.CLOSE JPY.CLOSE.1 JPY.CLOSE.2
2014-08-28 07:00:00 0.7713074    1.446201    1.446201

[[2]]
                     CHF.OPEN CHF.OPEN.1 CHF.OPEN.2
2014-08-28 07:00:00 0.6010272   1.464321   1.464321

[[3]]
                     CAD.CLOSE CAD.CLOSE.1 CAD.CLOSE.2
2014-08-28 07:00:00 -0.5892643   0.4879845   0.4879845

我还将tail(x, n = 1L)替换为last(x),因为在这种情况下它会产生相同的效果并且更易于阅读。删除了ret的预分配,因为lapply已经处理了它。

此外,根据您的应用程序,这可能是一个更好的代码: 使new.trend成为一个没有嵌套lapply的简单函数。 lapply sig就可以了。因此,您的sig将不会在此函数中进行硬编码。

new.trend <- function(MergedData, sig) {
  x <- MergedData[[sig]]
  x <- xts(x[, -1], order.by = x[, 1])
  dev20 <- (x[, 4] - x[, 5]) / x[, 4] * 100
  dev50 <- (x[, 4] - x[, 6]) / x[, 4] * 100
  RSI <- dev50
  merge(last(dev20), last(dev50), last(RSI))
}

sig <- c(2, 4, 6, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 24)
lapply(sig, new.trend, MergedData = MergedData)