R - 在 for 循环中命名多个函数 [英] R - Naming multiple functions in a for loop

查看:52
本文介绍了R - 在 for 循环中命名多个函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下数据框:

> coc_comp_model[1:3,]
    Relationship Output  Input |r-Value|   Y-Intercept   Gradient
1   DG-r ~ DG-cl   DG-r  DG-cl 0.8271167  0.0027217513 12.9901380
2 CA3-r ~ CA3-cl  CA3-r CA3-cl 0.7461309  0.0350767684 27.6107963
3 CA2-r ~ CA2-cl  CA2-r CA2-cl 0.9732584 -0.0040992226 35.8299582

我想为数据框的每一行创建简单的函数.这是我尝试过的:

I want to create simple functions for each row of the data frame. here's what I've tried:

for(i in 1:nrow(coc_comp_model)) {
coc_glm_f[i] <- function(x)
x*coc_comp_model$Gradient[i] + coc_comp_model$Y-Intercept[i]
}

还尝试制作函数向量,这也不起作用.

also tried making a vector of functions, which also does ont work either.

感谢您阅读本文/帮助.

Thanks for reading this/helping.

推荐答案

没有函数向量这样的东西.R中有6种原子向量类型:raw、logical、integer、double、complex、character,再加上异构列表类型,最后还有鲜为人知的表达式类型,基本上就是解析树的向量(比如当您接到替代() 函数).这些都是 R 中的向量类型.

There is no such thing as a vector of functions. There are 6 atomic vector types in R: raw, logical, integer, double, complex, and character, plus there is the heterogeneous list type, and finally there is the lesser known expression type, which is basically a vector of parse trees (such as you get from a call to the substitute() function). Those are all the vector types in R.

printAndType <- function(x) { print(x); typeof(x); };
printAndType(as.raw(1:3));
## [1] 01 02 03
## [1] "raw"
printAndType(c(T,F));
## [1]  TRUE FALSE
## [1] "logical"
printAndType(1:3);
## [1] 1 2 3
## [1] "integer"
printAndType(as.double(1:3));
## [1] 1 2 3
## [1] "double"
printAndType(c(1i,2i,3i));
## [1] 0+1i 0+2i 0+3i
## [1] "complex"
printAndType(letters[1:3]);
## [1] "a" "b" "c"
## [1] "character"
printAndType(list(c(T,F),1:3,letters[1:3]));
## [[1]]
## [1]  TRUE FALSE
##
## [[2]]
## [1] 1 2 3
##
## [[3]]
## [1] "a" "b" "c"
##
## [1] "list"
printAndType(expression(a+1,sum(1,2+3*4),if (T) 1 else 2));
## expression(a + 1, sum(1, 2 + 3 * 4), if (T) 1 else 2)
## [1] "expression"

如果要在单个对象中存储多个函数,则必须使用列表,并且必须在左值中使用双括号索引运算符才能为其赋值:

If you want to store multiple functions in a single object, you have to use a list, and you must use the double-bracket indexing operator in the lvalue to assign to it:

fl <- list();
for (i in 1:3) fl[[i]] <- (function(i) { force(i); function(a) a+i; })(i);
fl;
## [[1]]
## function (a)
## a + i
## <environment: 0x600da11a0>
##
## [[2]]
## function (a)
## a + i
## <environment: 0x600da1ab0>
##
## [[3]]
## function (a)
## a + i
## <environment: 0x600da23f8>
sapply(fl,function(f) environment(f)$i);
## [1] 1 2 3
sapply(fl,function(f) f(3));
## [1] 4 5 6

在上面的代码中,我还演示了关闭循环变量的正确方法.这需要创建一个临时函数评估环境来保存 i 的副本,然后返回的函数将围绕该评估环境关闭,以便它可以访问特定于迭代的 i.这适用于支持动态函数和闭包的其他语言,例如 JavaScript.在 R 中,还有一个额外的要求是通过 force(),否则,对于每个独立生成的函数,直到对特定生成的函数进行第一次评估时,promise 才会被解析,这将在那时锁定在该特定生成函数的承诺目标(在本例中为全局 i 变量)的当前值中.还应该提到的是,这是一种极其浪费的设计,每次迭代都生成一个临时函数并对其进行评估,这会生成一个带有循环变量副本的新评估环境.

In the above code I also demonstrate the proper way to closure around a loop variable. This requires creating a temporary function evaluation environment to hold a copy of i, and the returned function will then closure around that evaluation environment so that it can access the iteration-specific i. This holds true for other languages that support dynamic functions and closures, such as JavaScript. In R there is an additional requirement of forcing the promise to be resolved via force(), otherwise, for each generated function independently, the promise wouldn't be resolved until the first evaluation of that particular generated function, which would at that time lock in the current value of the promise target (the global i variable in this case) for that particular generated function. It should also be mentioned that this is an extremely wasteful design, to generate a temporary function for every iteration and evaluate it, which generates a new evaluation environment with a copy of the loop variable.

如果您想使用这种设计,那么您的代码将变为:

If you wanted to use this design then your code would become:

coc_glm_f <- list();
for (i in 1:nrow(coc_comp_model)) {
    coc_glm_f[[i]] <- (function(i) { force(i); function(x) x*coc_comp_model$Gradient[i] + coc_comp_model$`Y-Intercept`[i]; })(i);
};

然而,为 data.frame 的每一行创建一个单独的函数可能没有意义.如果您希望 x 参数采用标量值(我的意思是单元素向量),那么您可以按如下方式定义函数:

However, it probably doesn't make sense to create a separate function for every row of the data.frame. If you intended the x parameter to take a scalar value (by which I mean a one-element vector), then you can define the function as follows:

coc_glm_f <- function(x) x*coc_comp_model$Gradient + coc_comp_model$`Y-Intercept`;

这个函数是向量化的,意味着你可以为x传递一个向量,其中x的每个元素将对应一行coc_comp_model.例如:

This function is vectorized, meaning you can pass a vector for x, where each element of x would correspond to a row of coc_comp_model. For example:

coc_comp_model <- data.frame(Relationship=c('DG-r ~ DG-cl','CA3-r ~ CA3-cl','CA2-r ~ CA2-cl'),Output=c('DG-r','CA3-r','CA2-r'),Input=c('DG-cl','CA3-cl','CA2-cl'),`|r-Value|`=c(0.8271167,0.7461309,0.9732584),`Y-Intercept`=c(0.0027217513,0.0350767684,-0.0040992226),Gradient=c(12.9901380,27.6107963,35.8299582),check.names=F);
coc_glm_f(seq_len(nrow(coc_comp_model)));
## [1]  12.99286  55.25667 107.48578

这篇关于R - 在 for 循环中命名多个函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆