首页 > 解决方案 > 使用管道中的 ifelse 条件修改某些值

问题描述

假设我有如下数据框:

df <- structure(list( 
 name = c("A", "A", "A", "A", "B", "B", "B", "B"),
 val = c(100, 200, 300, 400, 0.15, 0.22, 0.31, 0.48)),
 .typeOf = c("factor", "numeric"),
 row.names = c(NA, -8L),
 class = "data.frame")

我想在条形图上使用线图来可视化数据。但是,您可能会看到数据具有不同的比例,因此我无法正常可视化它们。我需要分别从数据框中引入第二个 Y 轴并重新调整对象“B”的值。为此,我使用以下代码:

df %>%
{
 assign("scaleFactor", ifelse(max(.[.$name == "A",2], na.rm = T) > max(.[.$name == "B",2], na.rm = T),
                              max(.[.$name == "A",2], na.rm = T) / max(.[.$name == "B",2], na.rm = T),
                              max(.[.$name == "B",2], na.rm = T) / max(.[.$name == "A",2], na.rm = T)), 
         envir = baseenv())
 . } %>%
 mutate(val = ifelse(max(.[.$name == "A 1",2], na.rm = T) > max(.[.$name == "B",4], na.rm = T),
                     .[.$name == "B",2] <- .[.$name == "B",2] * scaleFactor,
                     .[.$name == "A",2] <- .[.$name == "B",2] * scaleFactor))

首先,我需要计算比例因子。它工作正常。然后我需要按比例因子对对象“B”的多个值。在这里我有一个问题。它返回只有一个重复值的第二列。似乎在这种情况下ifelse条件不能用作矢量化函数。

但是,如果我在管道/变异之外使用ifelse条件,它就可以工作。

ifelse(max(df[df$name == "A",2], na.rm = T) > max(df[df$name == "B",2], na.rm = T),
       df[df$name == "B",2] <- df[df$name == "B",2] * scaleFactor,
       df[df$name == "A",2] <- df[df$name == "A",2] * scaleFactor)

任何想法如何使用管道中的ifelse条件修改/乘以某些值?

标签: r

解决方案


给语句中的列赋值mutate()(就像你对 eg 所做的那样.[.$name == "B",2] <- )不是你应该使用的方式mutate,而且会让人头疼。

下面的代码给出了您期望的输出。我用 a 替换ifelsemax(max_val) / max_val,它立即给了scaleFactor你想要的。

library(dplyr)

df %>% 
  group_by(name) %>% 
  mutate(max_val = max(val, na.rm = T)) %>% 
  ungroup() %>% 
  mutate(scaleFactor = max(max_val) / max_val,
         val_scaled = val * scaleFactor)

这使

# A tibble: 8 x 5
  name     val max_val scaleFactor val_scaled
  <chr>  <dbl>   <dbl>       <dbl>      <dbl>
1 A     100     400             1        100 
2 A     200     400             1        200 
3 A     300     400             1        300 
4 A     400     400             1        400 
5 B       0.15    0.48        833.       125 
6 B       0.22    0.48        833.       183.
7 B       0.31    0.48        833.       258.
8 B       0.48    0.48        833.       400 

我在那里保留了额外的列,以便您可以看到发生了什么。select()您可以通过仅 ing 所需的列来删除它们。


推荐阅读