有条件地将字符串转换为特定的数值

时间:2019-02-14 12:06:06

标签: r dataframe if-statement sapply

我敢肯定有一个简单的答案,但是我已经扫描了堆栈溢出并且还没有找到解决方案。似乎将sapply和ifelse函数结合起来可以完成这项工作(但我不确定)。

所以我有一个带有字符的数据框,除了一列是数字值。

####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))

我想将此数据框中的字符转换为特定数字。字符需要转换为何种字符取决于最后一栏中的数字。因此标准是:

  • 如果Number = 1,则a应更改为30,b应更改为20,c应更改为10
  • 如果Number = 2,则a应该更改为35,b应该更改为25,c应该更改为15
  • 如果Number = 3,则a应该更改为40,b应该更改为30,c应该更改为20

以下是突出显示此转化的数据框

A <- c(30,20,10)
B <- c(35,25,15)
C <- c(40,30,20)
Conversion_df <- data.frame(A, B,C)

这是所需的输出。

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))

在此先感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

首先,我们可以使用if语句创建一个函数来评估样本:

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)))
}

在我们只需要在您的数据框中使用该函数之后:

df <- df %>% 
    mutate(
        Sample_1 = valuate_sample(Sample_1, Number),
        Sample_2 = valuate_sample(Sample_2, Number)
        )

结果:

enter image description here

答案 1 :(得分:1)

我也有一个case_when解决方案,但是使用的是 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) ) ,这也许更加透明。这个想法来自这个答案https://stackoverflow.com/a/24459900/5795592

#) libxml_disable_entity_loader(false); // above the WS SETTINGS and try it.

答案 2 :(得分:0)

根据@skulden在评论中描述的代码,您还可以在所有所需的列(即那些编码为数据帧中的因子的列)上自动应用“ valuate_sample”功能。

这里是@skulden在上一个答案中突出显示的功能。

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)))
}

这是将其应用于所有列的方法。

for(column in names(df)) { if(is.factor(df[,column])){

   df[,column] <- valuate_sample(df[,column], df[,'Number'])

}