R programming language resources › Forums › Data manipulation › applying if then else logic to a column in a data frame
Tagged: data manipulation, ifelse, recoding
- This topic has 3 replies, 2 voices, and was last updated 10 years, 5 months ago by
sander69.
- AuthorPosts
- November 16, 2014 at 5:12 pm #1075
sander69
MemberI am new to R and I am lost. My brain thinks in SAS and it’s not translating well into R.
I am trying to apply some if-else if logic to a column in a data frame. I want to assign a value to a new variable called DOL.Group, which is a vector with the same length as the variable I’m working off of (i.e. RawData$DOL).
This is the code I’ve written so far. In my mind, this code looks at the data vector RawData$DOL one element at a time and checks to see which list the element belongs to. The result SHOULD be a vector with 1,2 or 3 as values representing which list it belonged to.
########## CODE ###################
# SET WORKING DIRECTORY ;
dir<-“~/Dropbox/Research/Rifle Shot Optimization Project/Source Data”
setwd(dir)
getwd()# LOAD REGRESSION DATA
RawData<-read.csv(“SourceRifleData.csv”,header=TRUE)
attach(RawData)
names(RawData)# DELETE BAD UNITS
# UNITS 1.98, 2.17, 2.24 AND 2.29 ARE DUE TO TUMBLED BULLETS
Clean.Data<-subset(RawData, include==1)# COMBINE levels of Powder Charge (PC) and Distance Off Lands (DOL)
# DOL PC
# 0.0050 25.3000
# 0.0100 25.4000
# 0.0150 25.5000
# 0.0200 25.6000
# 0.0250 25.7000
# 0.0300 25.8000
# 26.9000
# 26.0000
# 26.1000
# 26.2000
#
# DOL GROUPS PC GROUPS
# 1 <- {0.0050, 0.0100} 1 <- {25.3, 25.4, 25.5}
# 2 <- {0.0150, 0.0200} 2 <- {25.6, 25.7, 25.8, 25.9}
# 3 <- {0.0250, 0.0300} 3 <- {26.0, 26.1, 26.2}DOLG1 <- c(0.0050, 0.0100)
DOLG2 <- c(0.0150, 0.0200)
DOLG3 <- c(0.0250, 0.0300)
DOL.Lth <= length(Clean.Data$DOL)
( ivals <- seq(1:DOL.Lth) )
DOL.Group <- as.vector( rep(0,402), mode=”numeric” )for (i in ivals)
{
if( Clean.Data$DOL[i] %in% DOLG1)
{
DOL.Group[i] = 1
} else {
if(Clean.Data$DOL[i] %in% DOLG2)
{
DOL.Group[i] = 2
} else {
if(Clean.Data$DOL[i] %in% DOLG3)
{
DOL.Group[i] = 3
}
}
}
}November 17, 2014 at 4:17 pm #1076bryan
ParticipantHi sander,
Welcome to R and ProgrammingR.com. A couple of suggestions:
1) Directly related to your question: use multiple ifelse() functions to create your groups. E.g,
DOL.group <- ifelse(Clean.Data$DOL %in% DOLG1, DOL.Group = 1, NA) DOL.group <- ifelse(Clean.Data$DOL %in% DOLG2, DOL.Group = 2, DOL.Group) DOL.group <- ifelse(Clean.Data$DOL %in% DOLG3, DOL.Group = 3, DOL.Group) Since ifelse() operates on vectors, you do not need to iterate through each row with a loop. There are other ways to do what you're asking, but this is a fine, straightforward way to handle it. 2) It's almost always a good idea to include stringsAsFators = 'FALSE' in your import command. It usually makes your data manipulations easier and less error prone, unless you are comfortable working with factors. 3) attach() can be more trouble than it is worth most of the time. I recommend against using it. I suspect 1) will fix your issue, but let us know if not. Bryan
November 17, 2014 at 4:23 pm #1077bryan
ParticipantAlso, as I look at your code again, I’m not clear how the groups should be defined in your DOLGX objects. If you’re just trying to classify based on ranges (not specific discrete values), you can set your ifelses up as so:
DOL.group <- ifelse(Clean.Data$DOL >= .005 & Clean.Data$DOL <= .01 , DOL.Group = 1, NA), etc.
November 18, 2014 at 9:11 pm #1079sander69
MemberThank you Bryan,
I ended up using the following code, but I like your ifelse example betterDOL1 <- which( DOL==0.0050 )
DOL2 <- which( DOL==0.0100 )
DOL3 <- which( DOL==0.0150 )
DOL4 <- which( DOL==0.0200 )
DOL5 <- which( DOL==0.0250 )
DOL6 <- which( DOL==0.0300 )ShotData[DOL1,”DOL.lvl”] <- 0;
ShotData[DOL2,”DOL.lvl”] <- 0;
ShotData[DOL3,”DOL.lvl”] <- .5;
ShotData[DOL4,”DOL.lvl”] <- .5;
ShotData[DOL5,”DOL.lvl”] <- 1;
ShotData[DOL6,”DOL.lvl”] <- 1; - AuthorPosts
- You must be logged in to reply to this topic.