【问题标题】:Creating new column based on criteria in three other columns根据其他三个列中的条件创建新列
【发布时间】:2021-03-28 21:14:29
【问题描述】:

谁能帮我根据一些严格的标准创建一个新列。

数据看起来像这样

screening consistancyAPP  consistancyVAF consistancyCRF
XXX/01    Missing         50-100% target 50-100% target
XXX/03    0-49% target    0-49% target   0-49% target
XXX/08    Missing         Missing        50-100% target
XXX/13    Missing         Missing        Missing
XXX/09    Missing         0-49% target   50-100% target
XXX/04    0-49% target    0-49% target   50-100% target
df <- data.frame (screening  = c("XXX/01", "XXX/03", "XXX/08","XXX/13","XXX/09","XXX/04"),
                  consistancyAPP = c("Missing", "0-49% target", "Missing","Missing","Missing","0-49% target"),
                  consistancyVAF = c("50-100% target", "0-49% target", "Missing","Missing","0-49% target","0-49% target"),
                  consistancyCRF = c("50-100% target", "0-49% target", "50-100% target","Missing","50-100% target","50-100% target")
)

新列的条件

  • 如果所有三个都相同,例如失踪然后失踪
  • 如果两个缺失(例如 XXX/08),则取另一个(例如 50-100% 目标)
  • 如果两个一致(例如 XXX/01),则该值(例如 50-100% 目标)
  • 如果所有三个不同的 (XXX/09) 都采用较低的(0-49% 目标)

我希望输出看起来像这样

screening consistancyAPP  consistancyVAF consistancyCRF  consistancyOverall
XXX/01    Missing         50-100% target 50-100% target  50-100% target
XXX/04    0-49% target    0-49% target   0-49% target    0-49% target
XXX/08    Missing         Missing        50-100% target  50-100% target
XXX/13    Missing         Missing        Missing         Missing
XXX/09    Missing         0-49% target   50-100% target  0-49% target
XXX/04    0-49% target    0-49% target   50-100% target  0-49% target

【问题讨论】:

  • 在你的例子中是所有可能的情况吗?是否有可能在您的数据中有 30-40% 的目标?
  • 只能是“缺失”、“0-49% 目标”、“50-100% 目标”。只有这三个级别
  • 正如您所说,您的列值是因素。因此,您可以转换为 factor(..., ordered = TRUE) 并使用它来选择结果。如果您可以提供一个工作示例,那么帮助您会更容易,这样我们就不需要自己创建 data.frame。
  • 添加了一个工作示例!

标签: r


【解决方案1】:

好的,我终于让我的功能工作了。 对于这个问题,我创建了一个函数,该函数采用长度为 3 的字符向量,并根据上述条件返回首选选项。然后,我们使用 dplyr 函数 rowwisemutate 将其应用于数据集的每一列:

score <- function(symbols) {
  
  same <- symbols[1] == symbols[2] && symbols[2] == symbols[3]
  two_same <- symbols[1] == symbols[2] || symbols[2] == symbols[[3]] ||
    symbols[1] == symbols[3]
  not_same <- symbols[1] != symbols[2] && symbols[1] != symbols[2] &&
    symbols[2] != symbols[3]
  two_missing <- sum(symbols == "Missing") == 2
  
  if(same) {
    return(symbols[1])
  } else if(not_same) {
    return("0-49% target")
  } else if(two_missing) {
    return(symbols[symbols != "Missing"])
  } else if(two_same) {
    return(symbols[duplicated(symbols)])
  }
}

x <- c("Missing", "50-100% target", "50-100% target")

score(x)
[1] "50-100% target"

y <- c("Missing", "0-49% target", "50-100% target")

score(y)
[1] "0-49% target"

z <- c("Missing", "Missing", "50-100% target")

score(z)
[1] "50-100% target"

现在我们将其应用于您的数据集,如下所示:

df %>%
  rowwise() %>%
  mutate(consistancyOverall = score(c_across(starts_with('consistancy'))))

# A tibble: 6 x 5
# Rowwise: 
  screening consistancyAPP consistancyVAF consistancyCRF consistancyOverall
  <chr>     <chr>          <chr>          <chr>          <chr>             
1 XXX/01    Missing        50-100% target 50-100% target 50-100% target    
2 XXX/03    0-49% target   0-49% target   0-49% target   0-49% target      
3 XXX/08    Missing        Missing        50-100% target 50-100% target    
4 XXX/13    Missing        Missing        Missing        Missing           
5 XXX/09    Missing        0-49% target   50-100% target 0-49% target      
6 XXX/04    0-49% target   0-49% target   50-100% target 0-49% target  

你也可以从purrr函数中使用pmap,但是,这次我们不使用rowwise,因为pmap对数据框的每一行都应用了一个函数:

df %>%
  mutate(consistancyOverall = pmap(list(consistancyAPP, consistancyVAF, consistancyCRF), 
                                   ~ score(c(...))))

  screening consistancyAPP consistancyVAF consistancyCRF consistancyOverall
1    XXX/01        Missing 50-100% target 50-100% target     50-100% target
2    XXX/03   0-49% target   0-49% target   0-49% target       0-49% target
3    XXX/08        Missing        Missing 50-100% target     50-100% target
4    XXX/13        Missing        Missing        Missing            Missing
5    XXX/09        Missing   0-49% target 50-100% target       0-49% target
6    XXX/04   0-49% target   0-49% target 50-100% target       0-49% target

【讨论】:

    【解决方案2】:

    您可以编写一个函数,根据条件返回输出并应用于每一行。

    library(dplyr)
    
    calculateOverall <- function(x) {
      tmp <- sort(table(x), decreasing = TRUE)
                #If all three are same
      case_when(n_distinct(x) == 1 ~ first(x),
                #If two missing take other
                sum(x == 'Missing') >= 2 ~ x[x!= 'Missing'][1], 
                #If two in agreement take that value
                tmp[1] >= 2 ~ names(tmp)[1], 
                #If all three different
                n_distinct(tmp) == 1 ~ '0-49% target')
    }
    
    df %>%
      rowwise() %>%
      mutate(consistancyOverall = calculateOverall(c_across(starts_with('consistancy'))))
    
    # screening consistancyAPP consistancyVAF consistancyCRF consistancyOverall
    #  <chr>     <chr>          <chr>          <chr>          <chr>             
    #1 XXX/01    Missing        50-100% target 50-100% target 50-100% target    
    #2 XXX/03    0-49% target   0-49% target   0-49% target   0-49% target      
    #3 XXX/08    Missing        Missing        50-100% target 50-100% target    
    #4 XXX/13    Missing        Missing        Missing        Missing           
    #5 XXX/09    Missing        0-49% target   50-100% target 0-49% target      
    #6 XXX/04    0-49% target   0-49% target   50-100% target 0-49% target      
    

    或者purrr::pmap_chr

    df %>%
      mutate(consistancyOverall = purrr::pmap_chr(select(., starts_with('consistancy')),
                                  ~calculateOverall(c(...))))
    

    【讨论】:

    • 非常感谢您的巨大贡献,我真的很感激。在这种情况下我只有一个问题,我们可以使用purrr 函数逐行对这 3 列应用函数吗?
    • 是的,我们可以使用pmap_chr。我更新了答案以包含该选项。
    • 我终于得到了我的功能来解决这个问题,我不知道该怎么感谢你。很遗憾我花了相当长的时间才离开它,我很高兴它终于奏效了。感谢您在这方面的合作,您将永远是我在 R 中的灵感之一。
    • 很高兴,您能够使其工作@AnoushiravanR。一切顺利。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-30
    • 2017-08-26
    • 2020-06-02
    • 2020-04-25
    • 1970-01-01
    • 2020-09-24
    • 1970-01-01
    相关资源
    最近更新 更多