[R] using nested ifelse and rowSums to create new variable?

Marc Schwartz marc_schwartz at comcast.net
Tue Nov 21 22:42:58 CET 2006


On Tue, 2006-11-21 at 15:24 -0600, Marc Schwartz wrote:
> On Tue, 2006-11-21 at 14:26 -0600, Tony N. Brown wrote:
> > Dear R-help community,
> > 
> > If I have a data.frame df as follows:
> > 
> > > df
> >    x1 x2 x3 x4 x5 x6
> > 1   5  5  1  1  2  1
> > 2   5  5  5  5  1  5
> > 3   1  5  5  5  5  5
> > 4   5  5  1  4  5  5
> > 5   5  1  5  2  4  1
> > 6   5  1  5  4  5  1
> > 7   5  1  5  4  4  5
> > 8   5  1  1  1  1  5
> > 9   1  5  1  1  2  5
> > 10  5  1  5  4  5  5
> > 11  1  5  5  2  1  1
> > 12  5  5  5  4  4  1
> > 13  1  5  1  4  4  1
> > 14  1  1  5  4  5  5
> > 15  1  5  5  4  5  1
> > 16  1  1  5  5  5  1
> > 17  5  5  5  2  2  5
> > 18  1  5  1  5  5  5
> > 19  5  5  5  2  4  5
> > 20  1  1  5  2  4  5
> > 
> > How can I create a variable that captures the pattern of responses 
> > and counts across rows?
> > 
> > I used the ifelse function and that works fine for the first two 
> > conditions (see R code below). But I need help figuring out how to 
> > count the number of scores in each row for columns x3, x4, x5, and 
> > x6 that are less than 4, conditional upon an ifelse. I then want to 
> > assign a value to the new variable based upon the count.
> > 
> > The new variable I want to create is called dep. Here's my R code:
> > 
> > dep<-with(df,
> >   ifelse((x1==5) & (x2==5), 0,
> >   ifelse((x1==1 & x2==1), 1,
> > 
> >   ifelse((x1==1 & x2==5) | (x1==5 & x2==1) &
> >   (rowSums(df[ ,c(x3, x4, x5, x6)]<4) ==1), 2,
> >   ifelse((x1==1 & x2==5) | (x1==5 & x2==1) &
> >   (rowSums(df[ ,c(x3, x4, x5, x6)]<4) ==2), 3,
> >   ifelse((x1==1 & x2==5) | (x1==5 & x2==1) &
> >   (rowSums(df[ ,c(x3, x4, x5, x6)]<4) ==3), 4,
> > 
> > 99))))))
> > 
> > dep
> >  0  1  2 99
> >  6  3  6  5
> > 
> > I expected dep to range from 0 to 4 and its length to be equal to 
> > 20.
> > 
> > Thanks in advance for your help and suggestions.
> 
> I may be a bit off in what your desired end result is, but perhaps this
> will provide some insight. I renamed your data frame to DF, since df is
> a function:
> 
> > apply(DF[, -(1:2)], 1, function(x) sum(x < 4))
>  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 
>  4  1  0  1  2  1  0  3  3  0  3  1  2  0  1  1  2  1  1  1 


Thanks to Dimitris' post tweaking my neurons, the above can of course be
simplified to:

> rowSums(DF[, -(1:2)] < 4)
 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 
 4  1  0  1  2  1  0  3  3  0  3  1  2  0  1  1  2  1  1  1 

Note that rowSums() will accept an all numeric data frame as an
argument, so the initial coercion is not required.

Hence:

TAB <- table(rowSums(DF[, -(1:2)] < 4),
             factor(rowSums(DF[, 1:2]), 
                    labels = c("(1,1)", "(5,1)|(1,5)", "(5,5)")))

TAB <- addmargins(TAB)


> TAB
     
      (1,1) (5,1)|(1,5) (5,5) Sum
  0       1           3     0   4
  1       2           3     4   9
  2       0           2     1   3
  3       0           3     0   3
  4       0           0     1   1
  Sum     3          11     6  20


HTH,

Marc
<Time for more coffee...>



More information about the R-help mailing list