функциональное программирование, итерации цикла в дочернем фрейме - PullRequest
0 голосов
/ 24 апреля 2018

Я хотел бы создать функцию для использования внутри функции цикла, однако дочерний элемент не может найти i из родительской функции for (i in 1:3).Как бы я избежать этой проблемы?Я думал, что это можно решить с помощью assign(X, envir=sys.frame(which=-1)), хотя я не уверен, где его разместить или выбрать рамку в этом случае ...

#simplified issue

parent.fxn = function(X) {
for (i in 1:3)
    child.fxn(X)
}

child.fxn = function(X) {
    return(X[i])
}


#ex. run_script
#parent.fxn(1:10)
#Error in child.fxn(X) : object 'i' not found

Для справки, вот версияфактического сценария, который я пытался написать (ниже) ... ошибка в моем сценарии (ниже) очень немного отличалась от моего упрощенного примера (выше), хотя я не уверен, почему.

library(cluster)
library(data.table)
library(magrittr)

data = data.table(x=runif(300), y=runif(300), z=runif(300))

master.fxn = function(DT, nlvls=3, data.cols=c("x", "y", "z")) {
    Lvls = paste0("Level_", 1:nlvls);
    for (i in 1:nlvls) {
            core.fxn(DT, Lvls, return.k=TRUE)
    }   
}

core.fxn = function(X, mkey, ...) {
    X[, c(mkey[i]):=cluster.fxn(.SD, ...), .SDcols=data.cols, by=c(mkey[0:(i-1)])] %>%
            setkeyv(c(mkey[1:i]))
}

cluster.fxn = function(X, return.ac=FALSE, return.k=FALSE) {
    a = agnes(X, metric="euclidean", method="ward", stand=TRUE)
    if (return.ac) return(a$ac)
    if (return.k) return(cutree(a, k=2))
}

#ex. run_script
#master.fxn(data)
#Error in eval(bysub, parent.frame(), parent.frame()) : object 'i' not found
* 1009И, наконец, вот рабочая версия фактического скрипта, который не использует функцию, которая использует [i] внутри цикла, но достигает желаемого результата.Эти сценарии сжаты, чтобы привести к ошибке.Это действительно упростило бы вещи в конечном продукте, если бы я мог заставить core.fxn работать внутри цикла master.fxn.
library(cluster)
library(data.table)
library(magrittr)

data = data.table(x=runif(300), y=runif(300), z=runif(300))

master.fxn = function(DT, nlvls=3, data.cols=c("x", "y", "z")) {
    Lvls = paste0("Level_", 1:nlvls);
    for (i in 1:nlvls) {
            DT[, c(Lvls[i]):=cluster.fxn(.SD, return.k=TRUE), .SDcols=data.cols, by=c(Lvls[0:(i-1)])] %>%
            setkeyv(c(Lvls[1:i]))
    }   
}

cluster.fxn = function(X, return.ac=FALSE, return.k=FALSE) {
    a = agnes(X, metric="euclidean", method="ward", stand=TRUE)
    if (return.ac) return(a$ac)
    if (return.k) return(cutree(a, k=2))
}

#ex. run_script
#> data
#             x          y         z
#  1: 0.1934689 0.67631296 0.3083592
#  2: 0.5267910 0.93186454 0.9583132
#  3: 0.5533244 0.37712457 0.4022132
#  4: 0.1886627 0.07535931 0.1171205
#  5: 0.7499003 0.90682684 0.6104284
# ---                               
#296: 0.7196245 0.80206991 0.6657839
#297: 0.2453930 0.06807955 0.8126690
#298: 0.3481978 0.23024162 0.4734052
#299: 0.2123976 0.27191432 0.1753336
#300: 0.7312911 0.89491793 0.5417281
#
#>master.fxn(data)
#data[, .SD[1], by=.(Level_1, Level_2, Level_3)]
   #Level_1 Level_2 Level_3         x          y          z
#1:       1       1       1 0.0584953 0.77933040 0.76432541
#2:       1       1       2 0.1814877 0.65263178 0.41425295
#3:       1       2       1 0.9932725 0.99409350 0.96849477
#4:       1       2       2 0.9102010 0.76071068 0.69283525
#5:       2       1       1 0.9040033 0.85361443 0.30636660
#6:       2       1       2 0.8026868 0.08595128 0.43176372
#7:       2       2       1 0.2167962 0.73551203 0.01174373
#8:       2       2       2 0.5592571 0.84508641 0.37382253
#> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...