'How can I switch values between columns for specific rows?

I was building my data set for some accounting work and accidentally made a mistake. I'd like to switch every instance of a Credit (column journalItemLine_creditAmount) in the account 3605 to a Debit (column journalItemLine_debitAmount) and every instance of a Debit to a Credit.

data<-read.csv(file.choose(),head=TRUE)  
fixed_data<-if(data$journalItemLine_account=="3605"){journalItemLine_debitAmount==journalItemLine_creditAmount}
fixed_data<-if(data$journalItemLine_account=="3605"){journalItemLine_creditAmount==journalItemLine_debitAmount}

Here's the error I'm getting. Error: unexpected '=' in " fixed_data<-if(data$journalItemLine_account="



Solution 1:[1]

I would need example data to verify, but transform should work too:

new_data <- transform(fixed_data, 
                      journalItemLine_debitAmount = ifelse(data$journalItemLine_account=="3605", journalItemLine_creditAmount, journalItemLine_debitAmount),
                      journalItemLine_creditAmount = ifelse(data$journalItemLine_account=="3605", journalItemLine_debitAmount, journalItemLine_creditAmount))

Solution 2:[2]

Cueing off of @qdread's comments, you have a few problems:

  1. if (a=1) ... fails because you are assigning, when you should be testing equality. Use if (a==1) ... instead.

  2. if requires its conditional to be exactly length 1, but that will only be the case if your frame has 1 row; 0 or more than 2 will give you a warning: "the condition has length > 1 and only the first element will be used". Instead, use ifelse(condition, then, else).

  3. Your reassignment should likely go into a column of the frame. Your fixed_data is a vector (which is fine) but is not actually present in the frame afterwards. In actuality, the ifelse recommended in #2 above doesn't know or care about frames, it just operates on vectors, so the "conditional", "then" (if true), and "else" (if false) arguments all need to be vectors of the same length (or length 1, recycled).

Your code should then look something like this (untested):

data <- read.csv(file.choose(), head = TRUE)
newcred <- ifelse(data$journalItemLine_account == "3605",
                  data$journalItemLine_debitAmount, data$journalItemLine_creditAmount)
newdebt <- ifelse(data$journalItemLine_account == "3605",
                  data$journalItemLine_creditAmount, data$journalItemLine_debitAmount)
data$journalItemLine_creditAmount <- newcred
data$journalItemLine_debitAmount  <- newdebt

(Again, untested!, please verify the changes before using this on all data.)

Solution 3:[3]

Try the following. It uses a logical index to get the values of interest.

inx <- data$journalItemLine_account == "3605"

tmp <- data$journalItemLine_debitAmount[inx]
data$journalItemLine_debitAmount[inx] <- data$journalItemLine_creditAmount[inx]
data$journalItemLine_creditAmount[inx] <- tmp

Final cleanup.

rm(inx, tmp)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 sumshyftw
Solution 2 r2evans
Solution 3 Rui Barradas