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

Tony N. Brown tony.n.brown at vanderbilt.edu
Fri Nov 24 20:10:07 CET 2006


Thanks Dimitris and Marc. The solution to my problem was found in a 
a combination of your suggestions. I created a count vector 
separately and referenced it as part of the nested ifelse 
statements (see below).

Cheers,
Tony

> count <- rowSums(DF[, 3:6] < 4)
> count
 1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20
 3  1  2  2  3  2  2  0  1  2  3  2  0  3  3  2  3  2  2  4
> DF2<-data.frame(DF, count)
> DF2
   x1 x2 x3 x4 x5 x6 count
1   5  1  1  1  2  5     3
2   5  5  5  5  4  1     1
3   5  1  1  5  4  1     2
4   5  5  1  4  5  1     2
5   1  1  1  2  4  1     3
6   1  1  1  4  1  5     2
7   5  5  1  4  1  5     2
8   1  5  5  5  5  5     0
9   5  1  5  4  2  5     1
10  5  1  1  1  4  5     2
11  1  1  1  1  4  1     3
12  5  5  5  1  2  5     2
13  5  5  5  4  4  5     0
14  5  1  1  2  1  5     3
15  1  5  1  1  2  5     3
16  1  1  5  5  2  1     2
17  1  1  5  2  2  1     3
18  1  5  5  2  4  1     2
19  5  1  1  2  5  5     2
20  1  1  1  2  2  1     4
> dep<-with(DF2,
+   ifelse((x1==5) & (x2==5), -2,
+   ifelse((x1==1 & x2==1), -1,
+   ifelse((x1==1 & x2==5) | (x1==5 & x2==1) &
+   (count==0), 0,
+   ifelse((x1==1 & x2==5) | (x1==5 & x2==1) &
+   (count==1), 1,
+   ifelse((x1==1 & x2==5) | (x1==5 & x2==1) &
+   (count==2), 2,
+   ifelse((x1==1 & x2==5) | (x1==5 & x2==1) &
+   (count==3), 3,
+   ifelse((x1==1 & x2==5) | (x1==5 & x2==1) &
+   (count==4), 4,
+ 99))))))))
> table(dep)
dep
-2 -1  0  1  2  3
 5  6  3  1  3  2


--On Tuesday, November 21, 2006 3:42 PM -0600 Marc Schwartz 
<marc_schwartz at comcast.net> wrote:

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



---------------------------------------
Tony N. Brown, Ph.D.
Assistant Professor of Sociology
Vanderbilt University
Phone:  (615) 322-7518
Fax:    (615) 322-7505
Email:  tony.n.brown at vanderbilt.edu



More information about the R-help mailing list