Reputation: 421
I have the following dataframe:
ID C1 C2
1 0 100
2 29 0
3 0 0
4 789 400
I want to indicate the "Type" based on the columns "C1" and "C2." For example, if C1 and C2 are both equal to 0 (or NA), it is "Type 1." If C1 != 0 and C2 = 0 (or NA), then it is "Type 2." Type 3 --> C1 = 0 (& NA), C2 != 0 Type 4 --> C1 != 0 and C2 != 0
The output should look something like this:
Type
Type 4
Type 2
Type 1
Type 3
I tried a few different ways:
for (i in 1:nrow(df))
{
if
((is.na(df[i,12]) == TRUE) | (df[i,12] == 0.00) &
(is.na(df[i,13]) == TRUE) | (df[i,13] == 0.00))
{
df2[i,1] = "Type 1"
}
else
{
df2[i,1] = "Other Type"
}
}
I didn't include all the conditions in the above for loop, but it is really slow.
Here's another method I tried (Not complete code, but just trying):
ifelse((is.na(Test_Customer[,2]) | Test_Customer[,2]==0), "Type 1", "Type 2")
For the ifelse statement, I'm guessing I have to wrap it into a function and then use apply function to apply it to all rows of the dataframe. However, does R take nested ifelse statements like "if" statements in excel?
If anyone knows an alternative way of doing this, that would be great! Thanks so much in advance!!
Upvotes: 2
Views: 1021
Reputation: 160447
I can only provide a start since you have not included logic to classify Types 3 and 4, but it shouldn't be hard to extend this to additional constraints.
You are very close with your ifelse
, and there is no need to use apply
:
## dat is data.frame from the OP
with(dat, ifelse((is.na(C1) | C1 == 0) & (is.na(C2) | C2 == 0), 1, 2))
## [1] 2 2 1 2
You can instead return literal character strings by replacing the 1
and 2
above, and this can be used by itself or added as a new column to the original data.frame.
Upvotes: 0
Reputation: 93833
You can use interaction
to get there, once you convert your data to 1/0
using sign
:
factor(do.call(interaction,sign(dat[-1])),labels=paste("Type",c(1,2,4,3)))
#[1] Type 4 Type 2 Type 1 Type 3
#Levels: Type 1 Type 2 Type 4 Type 3
This will show you what the coding refers to: (C1.C2 values):
do.call(interaction,sign(dat[-1]))
#[1] 0.1 1.0 0.0 1.1
#Levels: 0.0 1.0 0.1 1.1
I'd personally switch your Type 4 and Type 3 categories, but that's up to you I suppose.
Upvotes: 1