dimanche 13 décembre 2015

R Loop with conditions

I have a series of repeated IDs that I would like to assign to unique groups. The IDs repeat with different frequencies for example below:

# Example Data 
ID = c(101,102,103,104)
Repeats = c(2,3,1,3)
Data = data.frame(ID,Repeats)
> head(Data)
   ID Repeats
1 101       2
2 102       3
3 103       1
4 104       3

I would like the same repeated ID to stay within the same group. However, each group has limited capacity. For example in my desired output matrix each group can only accommodate 3 IDs:

# Create empty data frame for group annotation
# Add 3 rows in order to have more space for IDs
# Some groups will have NAs due to  keeping IDs together (I'm OK with that)
Target = data.frame(matrix(NA,nrow=(sum(Data$Repeats)+3),
                                   ncol=dim(Data)[2]))
names(Target)<-c("ID","Group")
Target$Group<-rep(1:3)
Target$Group<-sort(Target$Group)
> head(Target)
  ID Group
1 NA     1
2 NA     1
3 NA     1
4 NA     1
5 NA     2
6 NA     2

I can loop each ID to my Target data frame but this does not grantee that repeated IDs will stay together in the same group:

# Loop repeated IDs the groups 
IDs.repeat = rep(Data$ID, times=Data$Repeats)
# loop IDs to Targets to assign IDs to groups
for (i in 1:length(IDs.repeat))
{
  Target$ID[i]<-IDs.repeat[i]
}

For example in the loop above I get the same ID (102) across two groups (1 and 2):

> head(Target)
   ID Group
1 101     1
2 101     1
3 102     1
4 102     1
5 102     2
6 103     2

Instead I want the output to look like this:

> head(Target)
   ID Group
1 101     1
2 101     1
3  NA     1
4  NA     1
5 102     2
6 102     2

Anyone has a solution for IDs to stay within the same group if there is sufficient space after assigning IDs? I think that I need a loop and count NAs within that group and see if the NAs>= to the length of that unique ID. However, I don't know how to implement this simultaneously. Maybe nesting another loop for the j group?

Any help with the loop will be appreciated immensely!

Aucun commentaire:

Enregistrer un commentaire