[R] How to split two levels several times?

arun smartpink111 at yahoo.com
Fri Jul 26 14:32:25 CEST 2013


Hi Dennis,
No problem.

As I mentioned, I was under the understanding that "electrode1" occurs only in multiples of 3.  I think your earlier post sounded like that.  May be I was misunderstood.  So, my solution was based on that.  In the below table, I am not sure, how you wanted to split.  For ex. it is not clear, whether rows 1-5 (electrode1) are only in the first list element or should it include  the next electrode "electrode2" also?  Could you also show the expected output?

dat$Len
# [1]  5  4  5  3  5  6  4  5  4  3  4  6  3  5  3  4  3 12  5  6  4  6  3
 as.character(dat$Val)
# [1] "electrode1" "electrode2" "electrode1" "electrode3" "electrode1"
 #[6] "electrode4" "electrode2" "electrode1" "electrode2" "electrode3"
#[11] "electrode2" "electrode4" "electrode3" "electrode1" "electrode3"
#[16] "electrode2" "electrode3" "electrode4" "electrode1" "electrode4"
#[21] "electrode2" "electrode4" "electrode3"
A.K.



Hi Rui & Arun, 
really thanks for investing so much time to deal with this problem! 
The code works now for this specific example. However it is not 
generally robust for slightly different situations. For instance it 
cannot correctly handle a slight variation of the table where I have 
again 4 types of electrodes of certain lengths. Electrode4 exists only 6
 times. At the transition of the combinations 3-4 and 4-1 there are 12 
times electrode4 which stick together in the output $`9`. This leads to 
wrong splittings thereafter. Sorry for asking such tricky questions. 

New table XXX 

electrode	length 
electrode1	206 
electrode1	194 
electrode1	182 
electrode1	172 
electrode1	169 
electrode2	82 
electrode2	78 
electrode2	70 
electrode2	58 
electrode1	206 
electrode1	194 
electrode1	182 
electrode1	172 
electrode1	169 
electrode3	260 
electrode3	176 
electrode3	137 
electrode1	206 
electrode1	194 
electrode1	182 
electrode1	172 
electrode1	169 
electrode4	86 
electrode4	66 
electrode4	64 
electrode4	52 
electrode4	27 
electrode4	26 
electrode2	82 
electrode2	78 
electrode2	70 
electrode2	58 
electrode1	206 
electrode1	194 
electrode1	182 
electrode1	172 
electrode1	169 
electrode2	82 
electrode2	78 
electrode2	70 
electrode2	58 
electrode3	260 
electrode3	176 
electrode3	137 
electrode2	82 
electrode2	78 
electrode2	70 
electrode2	58 
electrode4	86 
electrode4	66 
electrode4	64 
electrode4	52 
electrode4	27 
electrode4	26 
electrode3	260 
electrode3	176 
electrode3	137 
electrode1	206 
electrode1	194 
electrode1	182 
electrode1	172 
electrode1	169 
electrode3	260 
electrode3	176 
electrode3	137 
electrode2	82 
electrode2	78 
electrode2	70 
electrode2	58 
electrode3	260 
electrode3	176 
electrode3	137 
electrode4	86 
electrode4	66 
electrode4	64 
electrode4	52 
electrode4	27 
electrode4	26 
electrode4	86 
electrode4	66 
electrode4	64 
electrode4	52 
electrode4	27 
electrode4	26 
electrode1	206 
electrode1	194 
electrode1	182 
electrode1	172 
electrode1	169 
electrode4	86 
electrode4	66 
electrode4	64 
electrode4	52 
electrode4	27 
electrode4	26 
electrode2	82 
electrode2	78 
electrode2	70 
electrode2	58 
electrode4	86 
electrode4	66 
electrode4	64 
electrode4	52 
electrode4	27 
electrode4	26 
electrode3	260 
electrode3	176 
electrode3	137 



----- Original Message -----
From: arun <smartpink111 at yahoo.com>
To: "dennis1991 at gmx.net" <dennis1991 at gmx.net>
Cc: 
Sent: Friday, July 26, 2013 1:05 AM
Subject: Re: [R] How to split two levels several times?

Just to add:
I assumed that "electrode1" would be found in multiples of 3.  I could be wrong.  



----- Original Message -----
From: arun <smartpink111 at yahoo.com>
To: Rui Barradas <ruipbarradas at sapo.pt>
Cc: "dennis1991 at gmx.net" <dennis1991 at gmx.net>; "r-help at r-project.org" <r-help at r-project.org>
Sent: Friday, July 26, 2013 12:53 AM
Subject: Re: [R] How to split two levels several times?



May be this also helps:
XXX: dataset
rl<-rle(as.character(XXX$electrode))
 dat<-do.call(rbind,lapply(seq_along(rl$lengths),function(i){x1<-if(rl$values[i]=="electrode1" & (rl$lengths[i]%/%3>1)) rep(3,rl$lengths[i]%/%3) else rl$lengths[i];data.frame(Len=x1,Val=rl$values[i])}))
 lst1<-split(cumsum(dat[,1]),((seq_along(dat[,1])-1)%/%2)+1)
vec1<-sapply(lst1,max)
vec2<-c(1,vec1[-length(vec1)]+1)
res<-  lapply(seq_along(lst1),function(i) {x1<-lst1[[i]]; XXX[seq(vec2[i],max(x1)),]})
 res
#[[1]]
 #  electrode length
#1 electrode1    5.7
#2 electrode1    6.3
#3 electrode1    6.2
#4 electrode2   11.4
#5 electrode2    9.7
#
#[[2]]
 #   electrode length
#6  electrode3   14.2
#7  electrode3   14.8
#8  electrode3   12.6
#9  electrode2   11.4
#10 electrode2    9.7
#
#[[3]]
 #   electrode length
#11 electrode4   17.0
#12 electrode4   16.3
#13 electrode4   17.8
#14 electrode4   18.3
#15 electrode4   16.9
#16 electrode4   18.5
#17 electrode1    5.7
#18 electrode1    6.3
#19 electrode1    6.2

#[[4]]
 #   electrode length
#20 electrode1    5.7
#21 electrode1    6.3
#22 electrode1    6.2
#23 electrode3   14.2
#24 electrode3   14.8
#25 electrode3   12.6

Also, tested in cases like below:
XXX1<- structure(list(electrode = structure(c(1L, 1L, 1L, 2L, 2L, 3L, 
3L, 3L, 2L, 2L, 4L, 4L, 4L, 4L, 4L, 4L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 3L, 3L, 3L), .Label = c("electrode1", 
"electrode2", "electrode3", "electrode4"), class = "factor"), 
    length = c(5.7, 6.3, 6.2, 11.4, 9.7, 14.2, 14.8, 12.6, 11.4, 
    9.7, 17, 16.3, 17.8, 18.3, 16.9, 18.5, 5.7, 6.3, 6.2, 7.7, 
    7.3, 6.2, 6.7, 6.8, 6.9, 5.7, 6.3, 6.2, 14.2, 14.8, 12.6)), .Names = c("electrode", 
"length"), class = "data.frame", row.names = c(NA, -31L))

XXX2<-structure(list(electrode = structure(c(1L, 1L, 1L, 2L, 2L, 3L, 
3L, 3L, 2L, 2L, 4L, 4L, 4L, 4L, 4L, 4L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 3L, 3L, 3L), .Label = c("electrode1", "electrode2", 
"electrode3", "electrode4"), class = "factor"), length = c(5.7, 
6.3, 6.2, 11.4, 9.7, 14.2, 14.8, 12.6, 11.4, 9.7, 17, 16.3, 17.8, 
18.3, 16.9, 18.5, 5.7, 6.3, 6.2, 7.7, 7.3, 6.2, 6.7, 6.8, 6.9, 
14.2, 14.8, 12.6)), .Names = c("electrode", "length"), class = "data.frame", row.names = c(NA, 
-28L))

rl<-rle(as.character(XXX1$electrode))
 dat<-do.call(rbind,lapply(seq_along(rl$lengths),function(i){x1<-if(rl$values[i]=="electrode1" & (rl$lengths[i]%/%3>1)) rep(3,rl$lengths[i]%/%3) else rl$lengths[i];data.frame(Len=x1,Val=rl$values[i])}))
 lst1<-split(cumsum(dat[,1]),((seq_along(dat[,1])-1)%/%2)+1)
vec1<-sapply(lst1,max)
vec2<-c(1,vec1[-length(vec1)]+1)
res1<-  lapply(seq_along(lst1),function(i) {x1<-lst1[[i]]; XXX1[seq(vec2[i],max(x1)),]})


rl<-rle(as.character(XXX2$electrode))
 dat<-do.call(rbind,lapply(seq_along(rl$lengths),function(i){x1<-if(rl$values[i]=="electrode1" & (rl$lengths[i]%/%3>1)) rep(3,rl$lengths[i]%/%3) else rl$lengths[i];data.frame(Len=x1,Val=rl$values[i])}))
 lst1<-split(cumsum(dat[,1]),((seq_along(dat[,1])-1)%/%2)+1)
vec1<-sapply(lst1,max)
vec2<-c(1,vec1[-length(vec1)]+1)
res2<-  lapply(seq_along(lst1),function(i) {x1<-lst1[[i]]; XXX2[seq(vec2[i],max(x1)),]})

Didn't test it extensively.  So, it may fail in other situations.
A.K.






----- Original Message -----
From: Rui Barradas <ruipbarradas at sapo.pt>
To: dennis1991 at gmx.net
Cc: r-help at r-project.org
Sent: Thursday, July 25, 2013 2:53 PM
Subject: Re: [R] How to split two levels several times?

Hello,

I think the following does what you want. (I don't know if it makes much 
sense but it works.)



lens <- rle(as.character(XXX$electrode))$lengths
m <- length(lens) %/% 2
idx <- rep(1:m, sapply(1:m, function(.m) sum(lens[(2*.m - 1):(2*.m)])))
if(length(lens) %% 2 != 0){
    idx <- c(idx, rep(m + 1, lens[length(lens)]))
    sp_idx <- split(idx, idx)
    n <- length(sp_idx[[m]])
    if(n %/% 2 < length(sp_idx[[m + 1]]))
        sp_idx[[m]][(n %/% 2 + 1):n] <- sp_idx[[m + 1]][1]
    else
        sp_idx[[m]][(n - length(sp_idx[[m + 1]]) + 1):n] <-  sp_idx[[m + 1]][1]
    idx <- unlist(sp_idx)
}

sp <- split(XXX, idx)
sp



Rui Barradas

Em 25-07-2013 11:40, dennis1991 at gmx.net escreveu:
> Hi Rui
> once more thank you for your help. But the code does so far not solve the problem because it still treats rows 17-22 (repeated appearance of electrode1) as one single level. However as can be seen by rows 1-3 (or rows 17-19 and rows 20-22) and the order of the length variable (row 1 = 5.7, row 2 = 6.3, row 3 = 6.2) electrode1 consists only of 3 rows. Maybe that was not made absolutely clear by me. As described in my mail before if by chance (or systematically) it happens to be that electrode1 appears right after each other in the table then the code should split it “half way”.
>
> So idx should not return
>   [1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4
>
> but instead 6 times number 4 at the end
>   [1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4
>
> Do you have any solution?
>
>
>> Gesendet: Mittwoch, 24. Juli 2013 um 23:47 Uhr
>> Von: "Rui Barradas" <ruipbarradas at sapo.pt>
>> An: dennis1991 at gmx.net
>> Cc: r-help at r-project.org
>> Betreff: Re: Aw: Re:  Re: [R] How to split two levels several times?
>>
>> Hello,
>>
>> As for the first question, note that in the case you describe, the
>> resulting list of df's will not be a split of the original, there will
>> be a duplication in the final 4-1 and 1-3. The following is a hack but
>> will do it.
>>
>>
>> lens <- rle(as.character(XXX$electrode))$lengths
>> m <- length(lens) %/% 2
>> idx <- rep(1:m, sapply(1:m, function(.m) sum(lens[(2*.m - 1):(2*.m)])))
>> if(length(lens) %% 2 != 0)
>>     idx <- c(idx, rep(m + 1, lens[length(lens)]))
>>
>> sp <- split(XXX, idx)
>>
>> if(length(lens) %% 2 != 0){
>>     idx2 <- sp[[m]]$electrode == sp[[m]]$electrode[nrow(sp[[m]])]
>>     sp[[m + 1]] <- rbind(sp[[m]][idx2, ], sp[[m + 1]])
>> }
>> sp
>>
>>
>> As for the second question, I'm not understanding it, can you post
>> sample output?
>>
>> Rui Barradas
>>
>> Em 24-07-2013 13:58, dennis1991 at gmx.net escreveu:
>>> Hi Rui
>>> the splitting code worked fine. Thanks for your help. Now I realized that the code cannot handle a table with levels that by chance (or systematically) repeatedly appear after each other. For instance this may happen if I need to extract the final two pairs of the table XXX below: electrode4+electrode1 and electrode1+electrode3.
>>>
>>> lens <- rle(as.character(XXX$electrode))$lengths
>>> will return 3 2 3 2 6 6 3 and not 3 2 3 2 6 3 3 3 because it counts electrode1 double.
>>> split(XXX, idx) will produce 3 incorrect outputs instead of the required 4.
>>> This will also occur if I have systematic combinations 1-4 after each other for instance in a new table “XX” below where electrode4 appears twice.
>>>
>>> Is there a way to make splitting "half-way" between two of the same levels possible by predefining the length of each individual level? This would make the splitting code more robust. Thanks for advice.
>>>
>>>
>>> This is the table "XXX"
>>>
>>> electrode length
>>>
>>> electrode1 5.7
>>> electrode1 6.3
>>> electrode1 6.2
>>> electrode2 11.4
>>> electrode2 9.7
>>> electrode3 14.2
>>> electrode3 14.8
>>> electrode3 12.6
>>> electrode2 11.4
>>> electrode2 9.7
>>> electrode4 17.0
>>> electrode4 16.3
>>> electrode4 17.8
>>> electrode4 18.3
>>> electrode4 16.9
>>> electrode4 18.5
>>> electrode1 5.7
>>> electrode1 6.3
>>> electrode1 6.2
>>> electrode1 5.7
>>> electrode1 6.3
>>> electrode1 6.2
>>> electrode3 14.2
>>> electrode3 14.8
>>> electrode3 12.6
>>>
>>>
>>> This is a simplified table XX
>>>
>>> electrode1
>>> electrode2
>>> electrode1
>>> electrode3
>>> electrode1
>>> electrode4
>>> electrode2
>>> electrode1
>>> electrode2
>>> electrode3
>>> electrode2
>>> electrode4
>>> electrode3
>>> electrode1
>>> electrode3
>>> electrode2
>>> electrode3
>>> electrode4
>>> electrode4
>>> electrode1
>>> electrode4
>>> electrode2
>>> electrode4
>>> electrode3
>>>
>>>
>>>
>>>
>>>
>>>
>>>> Gesendet: Dienstag, 23. Juli 2013 um 13:36 Uhr
>>>> Von: "Rui Barradas" <ruipbarradas at sapo.pt>
>>>> An: dennis1991 at gmx.net
>>>> Cc: smartpink111 at yahoo.com, 'r-help' <r-help at r-project.org>
>>>> Betreff: Re: Aw: Re: [R] How to split two levels several times?
>>>>
>>>> Hello,
>>>>
>>>> It's better if you keep this on the list, the odds of getting more and
>>>> better answers are greater.
>>>>
>>>> As for your new question, try the following.
>>>>
>>>>
>>>> lens <- rle(as.character(XXX$electrode))$lengths
>>>> m <- length(lens) %/% 2
>>>> idx <- rep(1:m, sapply(1:m, function(.m) sum(lens[(2*.m - 1):(2*.m)])))
>>>> split(XXX, idx)
>>>>
>>>>
>>>> Hope this helps,
>>>>
>>>> Rui Barradas
>>>>
>>>> Em 23-07-2013 11:41, dennis1991 at gmx.net escreveu:
>>>>> Hi
>>>>> this type of splitting works for my specific example. Thanks for your help.
>>>>>
>>>>> I was not absolutely clear what I generally want. I'm looking for an option that generally permits splitting two joint levels of a table after each other. For instance for the table below I want it to be divided into combinations electrode1-electrode2,  electrode3-electrode2,  electrode4-electrode1. How should I split this?
>>>>>
>>>>>
>>>>> This is the table "XXX"
>>>>>
>>>>> electrode length
>>>>>
>>>>> electrode1 5.7
>>>>> electrode1 6.3
>>>>> electrode1 6.2
>>>>> electrode2 11.4
>>>>> electrode2 9.7
>>>>> electrode3 14.2
>>>>> electrode3 14.8
>>>>> electrode3 12.6
>>>>> electrode2 11.4
>>>>> electrode2 9.7
>>>>> electrode4 17.0
>>>>> electrode4 16.3
>>>>> electrode4 17.8
>>>>> electrode4 18.3
>>>>> electrode4 16.9
>>>>> electrode4 18.5
>>>>> electrode1 5.7
>>>>> electrode1 6.3
>>>>> electrode1 6.2
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>> Gesendet: Montag, 22. Juli 2013 um 17:53 Uhr
>>>>>> Von: "Rui Barradas" <ruipbarradas at sapo.pt>
>>>>>> An: dennis1991 at gmx.net
>>>>>> Cc: r-help at r-project.org
>>>>>> Betreff: Re: [R] How to split two levels several times?
>>>>>>
>>>>>> Hello,
>>>>>>
>>>>>> Sorry, I've just realized that your data frame is named 'XXX', not
>>>>>> 'dat'. Change that and the rest should work:
>>>>>>
>>>>>>
>>>>>> idx <- cumsum(c(TRUE, diff(XXX$electrode == "electrode1") > 0))
>>>>>> split(XXX, idx)
>>>>>>
>>>>>>
>>>>>> Rui Barradas
>>>>>>
>>>>>> Em 22-07-2013 16:47, Rui Barradas escreveu:
>>>>>>> Hello,
>>>>>>>
>>>>>>> Try the following.
>>>>>>>
>>>>>>>
>>>>>>> idx <- cumsum(c(TRUE, diff(dat$electrode == "electrode1") > 0))
>>>>>>> split(dat, idx)
>>>>>>>
>>>>>>>
>>>>>>> Hope this helps,
>>>>>>>
>>>>>>> Rui Barradas
>>>>>>>
>>>>>>> Em 22-07-2013 15:09, dennis1991 at gmx.net escreveu:
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> I have a small problem with the function split() and would appreciate
>>>>>>>> your help.
>>>>>>>>
>>>>>>>> I have a table called “XXX” with 2 columns and 49 rows. The 49 rows
>>>>>>>> belong to 8 different levels (electrode1, ...,electrode8). I want to
>>>>>>>> split the table always at the row where “electrode1” starts again so
>>>>>>>> that I can export 7  individual dataframes (numbered “dataframe1” to
>>>>>>>> ”dataframe7”) which contain always electrode1 as first level (always
>>>>>>>> three rows) with the varying number of rows for electrodes2-8 below.
>>>>>>>> I tried the split function with various setups:
>>>>>>>>
>>>>>>>> t <- as.factor(XXX$electrode)
>>>>>>>>
>>>>>>>> dataframeX <- split(XXX, f=(levels=t))
>>>>>>>>
>>>>>>>> But this doesn’t work. Could you please help. Thank you! Dennis
>>>>>>>>
>>>>>>>>
>>>>>>>> This is the table "XXX"
>>>>>>>>
>>>>>>>> electrode    length
>>>>>>>>
>>>>>>>> electrode1    5.7
>>>>>>>> electrode1    6.3
>>>>>>>> electrode1    6.2
>>>>>>>> electrode2    11.4
>>>>>>>> electrode2    9.7
>>>>>>>> electrode1    5.7
>>>>>>>> electrode1    6.3
>>>>>>>> electrode1    6.2
>>>>>>>> electrode3    14.2
>>>>>>>> electrode3    14.8
>>>>>>>> electrode3    12.6
>>>>>>>> electrode1    5.7
>>>>>>>> electrode1    6.3
>>>>>>>> electrode1    6.2
>>>>>>>> electrode4    17.0
>>>>>>>> electrode4    16.3
>>>>>>>> electrode4    17.8
>>>>>>>> electrode4    18.3
>>>>>>>> electrode4    16.9
>>>>>>>> electrode4    18.5
>>>>>>>> electrode1    ....
>>>>>>>> ....        ....
>>>>>>>> electrode5    ....
>>>>>>>> ....        ....
>>>>>>>> electrode1    ....
>>>>>>>> electrode6    ....
>>>>>>>> electrode1    ....
>>>>>>>> electrode7    ....
>>>>>>>> electrode1    ....
>>>>>>>> electrode8    ....
>>>>>>>>
>>>>>>>> ______________________________________________
>>>>>>>> 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.
>>>>>>>>
>>>>>>>
>>>>>>> ______________________________________________
>>>>>>> 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.
>>>>>>
>>>>
>>

______________________________________________
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.




More information about the R-help mailing list