如何放置与任何for循环等效的apply [英] How to put an apply equivalent to any for loop

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

问题描述

大多数pro R用户建议我不要在R中使用循环.请改用Apply函数.问题在于,如果您不熟悉函数式编程,那么为每个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是矢量化的,在这里基本上用于转换矢量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循环等效的apply的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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