Skip to content

ifelse to speed up loop?

11 messages · Jeffrey Fuerte, arun, Bert Gunter +2 more

#
Your query is a little unclear to me, but I suspect
?rle
is what you want.

-- Bert
On Thu, Jan 24, 2013 at 1:20 PM, Jeffrey Fuerte <fuertejn at vcu.edu> wrote:

  
    
#
Hi,
You could do this:
test<-read.table(text="
? V1
1? 1
2? 1
3? 1
4? 2
5? 2
6? 2
7? 1
8? 1
9? 1
10? 2
11? 2
12? 2
",sep="",header=T)

?test$Group<-cumsum(abs(c(0,diff(test[,1]))))+1
test
#?? V1 Group
#1?? 1???? 1
#2?? 1???? 1
#3?? 1???? 1
#4?? 2???? 2
#5?? 2???? 2
#6?? 2???? 2
#7?? 1???? 3
#?? 1???? 3
#9?? 1???? 3
#10? 2???? 4
#11? 2???? 4
#12? 2???? 4
A.K.



----- Original Message -----
From: Jeffrey Fuerte <fuertejn at vcu.edu>
To: r-help at r-project.org
Cc: 
Sent: Thursday, January 24, 2013 4:20 PM
Subject: [R] ifelse to speed up loop?

Hello,

I'm not sure how to explain what I'm looking for but essentially I have a
test dataset that looks like this:

test:
?  V1
1?  1
2?  1
3?  1
4?  2
5?  2
6?  2
7?  1
8?  1
9?  1
10? 2
11? 2
12? 2

And what I want to be able to do is create another column that captures a
"grouping" variable that looks like this:

test
?  V1 group
1?  1? 1
2?  1? 1
3?  1? 1
4?  2? 2
5?  2? 2
6?  2? 2
7?  1 3
8?  1? 3
9?  1? 3
10? 2? 4
11? 2? 4
12? 2? 4

So, it's keeping track of the changes in V1, but even though V1 could be
the same in different instances, the group is treating it as a new group.
I have written a loop that does what I want, but this takes too long to
run, so I was hoping for either a faster approach or an ifelse statement.
Any ideas?

By the loop I was using looks like this:

groupings <- 1
test$group[1] <- groupings
for (i in 2:length(test$V1))
{
if (test$V1[i]==test$V1[i-1])
{
test$group[i] <- groupings
} else {
groupings <- groupings+1
test$group[i] <- groupings
}
}

Thanks for the help.

??? [[alternative HTML version deleted]]

______________________________________________
R-help at r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
#
HI,

This might be better.
test$group<-cumsum(abs(c(1,diff(test[,1]))))
A.K.




----- Original Message -----
From: Jeffrey Fuerte <fuertejn at vcu.edu>
To: r-help at r-project.org
Cc: 
Sent: Thursday, January 24, 2013 4:20 PM
Subject: [R] ifelse to speed up loop?

Hello,

I'm not sure how to explain what I'm looking for but essentially I have a
test dataset that looks like this:

test:
?  V1
1?  1
2?  1
3?  1
4?  2
5?  2
6?  2
7?  1
8?  1
9?  1
10? 2
11? 2
12? 2

And what I want to be able to do is create another column that captures a
"grouping" variable that looks like this:

test
?  V1 group
1?  1? 1
2?  1? 1
3?  1? 1
4?  2? 2
5?  2? 2
6?  2? 2
7?  1 3
8?  1? 3
9?  1? 3
10? 2? 4
11? 2? 4
12? 2? 4

So, it's keeping track of the changes in V1, but even though V1 could be
the same in different instances, the group is treating it as a new group.
I have written a loop that does what I want, but this takes too long to
run, so I was hoping for either a faster approach or an ifelse statement.
Any ideas?

By the loop I was using looks like this:

groupings <- 1
test$group[1] <- groupings
for (i in 2:length(test$V1))
{
if (test$V1[i]==test$V1[i-1])
{
test$group[i] <- groupings
} else {
groupings <- groupings+1
test$group[i] <- groupings
}
}

Thanks for the help.

??? [[alternative HTML version deleted]]

______________________________________________
R-help at r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
#
I should add that if your V1 column is numeric, fiddling around with
?diff or equivalent will also identify the groupings for you and may
be faster than rle().

-- Bert
On Thu, Jan 24, 2013 at 3:32 PM, Bert Gunter <bgunter at gene.com> wrote:

  
    
#
I like
   v <- test[,1]
   c(TRUE, cumsum( v[-length(v)] != v[-1] ))
(R's arithmetic on logicals treats TRUE as 1 and FALSE as 0.)

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com
#
Hi,

I guess you meant:
c(TRUE, cumsum( v[-length(v)] != v[-1] ))
?[1] 1 0 0 1 1 1 2 2 2 3 3 3
this:
?cumsum(c(TRUE, v[-length(v)] != v[-1] ))
# [1] 1 1 1 2 2 2 3 3 3 4 4 4
A.K.




----- Original Message -----
From: William Dunlap <wdunlap at tibco.com>
To: arun <smartpink111 at yahoo.com>; Jeffrey Fuerte <fuertejn at vcu.edu>
Cc: R help <r-help at r-project.org>
Sent: Thursday, January 24, 2013 6:48 PM
Subject: RE: [R] ifelse to speed up loop?

I like
?  v <- test[,1]
?  c(TRUE, cumsum( v[-length(v)] != v[-1] ))
(R's arithmetic on logicals treats TRUE as 1 and FALSE as 0.)

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com
#
Yes.

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com
#
Thank you for the tips. I should mention that the V1 is numeric in this case but I am trying to automate the overall procedure so it may not be numeric always. Would that matter with these functions?

Sent from my iPhone
On Jan 24, 2013, at 6:34 PM, arun <smartpink111 at yahoo.com> wrote:

            
#
rle() or c(TRUE, cumsum( v[-length(v)] != v[-1] )) will work on any
type for which != is defined.  The ones involving diff() require numeric inputs.

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com
#
Hi,
If variable `V1` is factor and it follows the same pattern as in your example:
test<- structure(list(V1 = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 
1L, 2L, 2L, 2L), .Label = c("a", "b"), class = "factor")), .Names = "V1", class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"))

test$group<-cumsum(c(1,abs(diff(as.integer(test[,1]))))) #works

#But, if it is like this:
test1<- structure(list(V1 = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 
1L, 3L, 3L, 3L), .Label = c("a", "b", "d"), class = "factor")), .Names = "V1", class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"))
?test1$group<-cumsum(c(1,abs(diff(as.integer(test1[,1]))))) #may not work well (depends on your expected result)
?v<- test1[,1] #Bill's solution
test1$group2<-cumsum(c(TRUE, v[-length(v)] != v[-1] ))# works
?test1
#? V1 group group2
#1?? a???? 1????? 1
#2?? a???? 1????? 1
#3?? a???? 1????? 1
#4?? b???? 2????? 2
#5?? b???? 2????? 2
#6?? b???? 2????? 2
#7?? a???? 3????? 3
#8?? a???? 3????? 3
#9?? a???? 3????? 3
#10? d???? 5????? 4
#11? d???? 5????? 4
#12? d???? 5????? 4

A.K.







----- Original Message -----
From: Jeff <fuertejn at mymail.vcu.edu>
To: arun <smartpink111 at yahoo.com>
Cc: Jeffrey Fuerte <fuertejn at vcu.edu>; R help <r-help at r-project.org>
Sent: Thursday, January 24, 2013 7:08 PM
Subject: Re: [R] ifelse to speed up loop?

Thank you for the tips. I should mention that the V1 is numeric in this case but I am trying to automate the overall procedure so it may not be numeric always. Would that matter with these functions?

Sent from my iPhone
On Jan 24, 2013, at 6:34 PM, arun <smartpink111 at yahoo.com> wrote: