[R] problem with function that adds rows to dataframe based on conditional statement

Curtis Burkhalter curtisburkhalter at gmail.com
Fri Mar 6 22:00:32 CET 2015


Hey Tom,

This solution works great, but if I try to then insert it in my function
that I've displayed above and apply it to my split dataframe I get the
error message:

Error in `[.default`(xj, i) : invalid subscript type 'list'

The reason why I need to try and get this to work within the function is
that I'm trying to apply it to a much larger dataframe
(nrow=12000,ncol=14). The actual data I'm working with consists of a
sampling year, a site, and a bunch of response variables. For each sampling
year by site combination I have 3 within year sampling occasions. For the
sampling year by site combinations that don't have 3 sampling events I need
to fill in the missing occasions with the NAs.

Can you see why I might be getting this error message?

Thanks



On Fri, Mar 6, 2015 at 1:48 PM, Tom Wright <tom at maladmin.com> wrote:

> If all you want is to add a row of na's could you just do something
> like:
>
> nExpectedRows<-length(unique(animals)) * length(unique(animalYears)) * 2
>
> newDf<-data.frame(animals=rep(NA,nExpectedRows-nrow(comAn)),
>                   animalYears=rep(NA,nExpectedRows-nrow(comAn)),
>                   animalMass=rep(NA,nExpectedRows-nrow(comAn)))
>
> comAn = rbind(comAn,newDf)
>
>
>
> On Thu, 2015-03-05 at 13:41 -0700, Curtis Burkhalter wrote:
> > Hello everyone,
> >
> > I'm having a problem with a function that I wrote that is supposed to
> add a
> > row to dataframe based upon a conditional statement. To explain I've used
> > an example below:
> >
> > #create data frame
> > animals=c("bird","dog","cat")
> > animals=rep(animals,each=4)
> > animals=animals[1:11]
> > animalYears=c(1,1,2,2,1,1,2,2,1,1,2)
> > animalMass=round(runif(11,min=10,max=50),0)
> >
> > comAn=as.data.frame(cbind(animals,animalYears,animalMass))
> > comAn
> >
> >   * animals* *animalYears* *animalMass*
> > 1     bird           1         30
> > 2     bird           1         32
> > 3     bird           2         27
> > 4     bird           2         16
> > 5      dog           1         22
> > 6      dog           1         25
> > 7      dog           2         41
> > 8      dog           2         22
> > 9      cat           1         30
> > 10     cat           1         37
> > 11     cat           2         49
> >
> > We can see here that for every type of animal I have two years of mass
> > measurements, except for the cat in year 2. What I want to do is add an
> > additional row to the end of the dataframe that consists strictly of NAs
> > and then I can substitute those out later.
> >
> > So what I first did was split the 'comAn' dataframe into the different
> > Animal by Year combos.
> >
> > #This line splits 'com_An' into a list ordered by the Animal by Year
> combos
> > comAn_split=split(comAn, paste(comAn$animals,comAn$animalYear))
> >
> > Then I wrote the function that identifies whether a particular Animal by
> > Year combo is less than two rows in length and if so it should add
> another
> > row that consists only of NAs using the vector 'NAs':
> >
> > #This function identifies the length of each Animal by Year combo and
> then
> > #uses the rbind function built in R to add a row
> > #to each animal by year combo if they have less than 2 samples
> >
> > addNA <- function(comAn) {
> >   NAs=c(NA,NA,NA)
> >         ind <- seq_len(nrow(comAn))
> >         comAn[ifelse(length(ind)<2,rbind(NAs),length(ind)),]
> > }
> >
> > #This applies the function addNs to the animals data organized in list
> > format
> > addedNAcomAn <- do.call(rbind, lapply(comAn_split, addNA))
> > addedNAcomAn
> >
> > When I apply the function to the list of the different Animal by Year
> > combos this is what I get:
> >        animals animalYears animalMass
> > bird 1    bird           1         23
> > bird 2    bird           2         50
> > cat 1      cat           1         15
> > cat 2     <NA>        <NA>       <NA>
> > dog 1      dog           1         23
> > dog 2      dog           2         38
> >
> > What I expect is this:
> >
> >    animals animalYears animalMass
> > 1     bird           1         41
> > 2     bird           1         23
> > 3     bird           2         23
> > 4     bird           2         50
> > 5      dog           1         49
> > 6      dog           1         23
> > 7      dog           2         13
> > 8      dog           2         38
> > 9      cat           1         42
> > 10     cat           1         15
> > 11     cat           2         33
> > 12     NA           NA      NA
> >
> > Am I conditioning improperly within the function or am I missing
> something
> > else. Any help would be greatly appreciated.
> >
> > Best
> >
>
>
>


-- 
Curtis Burkhalter

https://sites.google.com/site/curtisburkhalter/

	[[alternative HTML version deleted]]



More information about the R-help mailing list