问题
I'm sure there is an easy answer for this , but I have scanned stack overflow and haven't been able to find a solution. It would seem that potentially a combination of sapply and ifelse functions would do the job (but I'm not sure).
So I have a dataframe with characters, except one column which is a numeric value.
####Create dataframe which needs converting
df <- data.frame(Sample_1 = rep(letters[1:3], each = 3),
Sample_2 = rep("a", times = 9))
df$Number <- rep(seq(from=1,to=3,by=1))
I would like to convert the characters in this dataframe to a specific number. What the character needs to be converted to depends on the number in the final column. So the criteria would be:
- If Number = 1, then a should change to 30, b should change to 20 and c should change to 10
- If Number = 2, then a should change to 35, b should change to 25 and c should change to 15
- If Number = 3, then a should change to 40, b should change to 30 and c should change to 20
Here is a dataframe highlighting this conversion
A <- c(30,20,10)
B <- c(35,25,15)
C <- c(40,30,20)
Conversion_df <- data.frame(A, B,C)
And here is the desired output.
Final <- data.frame(Sample_1 = c(30,20,10,35,25,15,40,30,20),
Sample_2 = c(30,20,10,30,20,10,30,20,10))
Thank you in advance for any help.
回答1:
First we can create a function to valuate the sample with if's statements:
valuate_sample <- function(x,y) {
ifelse(y==1, ifelse(x=='a',30, ifelse(x=='b',20, 10)),
ifelse(y==2, ifelse(x=='a',35, ifelse(x=='b',25, 15)),
ifelse(y==3, ifelse(x=='a',40, ifelse(x=='b',30, 20)),0)))
}
After we just need to use the function in your dataframe:
df <- df %>%
mutate(
Sample_1 = valuate_sample(Sample_1, Number),
Sample_2 = valuate_sample(Sample_2, Number)
)
Result:
回答2:
I also have a dplyr
solution, but using case_when
, which is perhaps a bit more transparent. The idea is taken from this answer https://stackoverflow.com/a/24459900/5795592
library(dplyr)
df %>% mutate( # Sample_1
Sample_1_conv = case_when( Number == 1 & Sample_1 == "a" ~ 30
, Number == 1 & Sample_1 == "b" ~ 25
, Number == 1 & Sample_1 == "c" ~ 10
, Number == 2 & Sample_1 == "a" ~ 35
, Number == 2 & Sample_1 == "b" ~ 25
, Number == 2 & Sample_1 == "c" ~ 15
, Number == 3 & Sample_1 == "a" ~ 40
, Number == 3 & Sample_1 == "b" ~ 30
, Number == 3 & Sample_1 == "c" ~ 20)
# Sample_2
, Sample_2_conv = case_when( Number == 1 & Sample_2 == "a" ~ 30
, Number == 1 & Sample_2 == "b" ~ 25
, Number == 1 & Sample_2 == "c" ~ 10
, Number == 2 & Sample_2 == "a" ~ 35
, Number == 2 & Sample_2 == "b" ~ 25
, Number == 2 & Sample_2 == "c" ~ 15
, Number == 3 & Sample_2 == "a" ~ 40
, Number == 3 & Sample_2 == "b" ~ 30
, Number == 3 & Sample_2 == "c" ~ 20)
)
回答3:
As per the code described by @skulden in the comments, you can also apply the 'valuate_sample' function automatically across all of the desired columns (i.e. those coded as factors within the dataframe).
Here is the function highlighted by @skulden in a previous answer.
valuate_sample <- function(x,y) {
ifelse(y==1, ifelse(x=='a',30, ifelse(x=='b',20, 10)),
ifelse(y==2, ifelse(x=='a',35, ifelse(x=='b',25, 15)),
ifelse(y==3, ifelse(x=='a',40, ifelse(x=='b',30, 20)),0)))
}
And here is how this can be applied to all columns.
for(column in names(df)) { if(is.factor(df[,column])){
df[,column] <- valuate_sample(df[,column], df[,'Number'])
}
来源:https://stackoverflow.com/questions/54690043/conditionally-convert-strings-to-a-specific-numeric-value