如何将应用等效于任何 for 循环 [英] How to put an apply equivalent to any for loop
问题描述
大多数专业 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屋!