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

查看:125
本文介绍了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种原子向量类型:原始,逻辑,整数,双精度,复数和字符,再加上异构列表类型,最后还有鲜为人知的表达式类型,它基本上是解析树的向量(例如当您通过调用 replace() 函数).这些都是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天全站免登陆