'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:
if (a=1) ...
fails because you are assigning, when you should be testing equality. Useif (a==1) ...
instead.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, useifelse(condition, then, else)
.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, theifelse
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 |