[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