如何放置与任何for循环等效的apply [英] How to put an apply equivalent to any for loop
问题描述
大多数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屋!