如何将应用等效于任何 for 循环 [英] How to put an apply equivalent to any for loop

查看:31
本文介绍了如何将应用等效于任何 for 循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大多数专业 R 用户都建议我不要在 R 中使用循环.而是使用应用函数.问题是,如果您不熟悉函数式编程,那么为每个 for/while 循环编写一个等效的应用程序并不是那么直观.以下面的例子为例.

Most pro R users have advised me never to use loops in R. Use apply functions instead. The problem is that it is not that intuitive to write an apply equivalent for every for/while loop if you're not familiar with functional programming. Take the below example for instance.

F <- data.frame(name = c("a", "b", "c", "d"), var1 = c(1,0,0,1), var2 = c(0,0,1,1),  
var3 = c(1,1,1,1), clus = c("one", "two", "three", "four"))
F$ObjTrim <- ""
for (i in 1:nrow(F))
{
 for (j in 2:(ncol(F)-1))
{
 if(F[i, j] == 1) 
 {F$ObjTrim[i]  <- paste(F$ObjTrim[i], colnames(F)[j], sep = " ") }

 }
  print(i)
}

这里的目标是创建一个变量ObjTrim",该变量采用所有具有值 == 1 的列名称的值.有人可以建议一个与此等效的好的应用程序吗?

The objective here is to create a variable "ObjTrim" that takes the value of all the column names that have a value == 1. Can some one suggest a good apply equivalent to this?

例如上面的代码将给出:

The code above for example will give :

 name var1 var2 var3  clus         ObjTrim
1    a    1    0    1   one       var1 var3
2    b    0    0    1   two            var3
3    c    0    1    1 three       var2 var3
4    d    1    1    1  four  var1 var2 var3

谢谢!

推荐答案

在这里你可以使用 vectorization 避免 for 循环: colSums is vectorized并且在这里基本上用于将向量 c(TRUE,FALSE) 转换为 0 或 1.

Here you can avoid for loops using vectorization: colSums is vectorized and is basically used here to convert a vector c(TRUE,FALSE) to 0 or 1.

 colnames(F)[colSums(F==1) != 0] ## create 

这是使用我的可重现示例进行的测试:

Here is a test using my reproducible example:

set.seed(1234)
## create matrix 2*10
F <- matrix(sample(c(1:5),20,rep=TRUE),nrow=2,
            dimnames = list(c('row1','row2'),paste0('col',1:10)))

#        col1 col2 col3 col4 col5 col6 col7 col8 col9 col10
# row1    1    4    5    1    4    4    2    2    2     1
# row2    4    4    4    2    3    3    5    5    2     2
colnames(F)[colSums(F==1) != 0]
"col1"  "col4"  "col10"

PS:通常很容易用R 风格的解决方案"替换 for 循环,但在某些情况下很难/不可能专门这样做当有递归时.

PS: Generally it is easy to replace for loops by an "R style solution", but there are some cases where it is difficult/impossible to do that specially when there is recursion.

编辑

在 OP 澄清之后,这是一个 apply 解决方案:

After OP's clarification , here is an apply solution :

F$ObjTrim <- apply(F,1,function(x) paste(colnames(F)[x==1],collapse=' '))

 name var1 var2 var3  clus        ObjTrim
1    a    1    0    1   one      var1 var3
2    b    0    0    1   two           var3
3    c    0    1    1 three      var2 var3
4    d    1    1    1  four var1 var2 var3

这篇关于如何将应用等效于任何 for 循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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