如何基于多个条件语句创建多个新列?

问题描述 投票:1回答:2

[第一堆问题请亲切的:)]

我正在基于现有列的多个条件语句在数据框中创建多个新列 - 所有基本上是新的列组合。

例如,如果有4列(a:d),我需要所有组合的新列(abcd,abc,abd等)和基于阈值数据的0/1编码:d。

包括玩具数据示例和期望的结果。但是需要可扩展:有4个基本列,但我需要2,3和4列的所有组合,而不仅仅是3个值(abc,abd,.... ab,ac,ad,... total n = 11)

[背景背景:这实际上是来自多能干细胞的流式细胞仪数据,可以生长成所有谱系细胞类型(多能或abcd)或逐渐受限制的群体(仅abc,或abdabac等)的集落。

# Toy data set
set.seed(123)
df <- tibble(a = c(sample(10:50, 10)),
             b = c(sample(10:50, 10)),
             c = c(sample(10:50, 10)),
             d = c(sample(10:50, 10)))

当前代码产生了所需的结果,但是,这需要11行重复代码,这很容易出错,我希望有一个更优雅的解决方案:

df %>% 
  mutate(
    abcd = if_else(a > 30 & b > 20 & c > 30 & d > 30, 1, 0),
    abc = if_else(a > 30 & b > 20 & c > 30 & d <= 30, 1, 0),
    abd = if_else(a > 30 & b > 20 & c <= 30 & d > 30, 1, 0),
    acd = if_else(a > 30 & b <= 20 & c > 30 & d > 30, 1, 0),
    bcd = if_else(a <= 30 & b > 20 & c > 30 & d > 30, 1, 0))
r conditional
2个回答
2
投票

我从您的问题中了解到,对于每一行,您只需要找到哪些列符合ifelse()条件中定义的条件。此向量化解决方案将向df添加一列,其中包含所有组合。这也可能比多个ifelse条件更快。最后,新列可用于订购或分组。

# define the threshold levels for all columns
threshold = c(a=30, b=20, c=30, d=30)

# get names of columns meeting the threshold and paste names
df$combn <- apply(df, 1, function(x) {
  paste(names(x)[x > threshold], collapse = "")
})

> df
# A tibble: 10 x 5
       a     b     c     d combn
   <int> <int> <int> <int> <chr>
 1    21    49    46    49 bcd  
 2    41    28    37    46 abcd 
 3    25    36    34    36 bcd  
 4    43    31    47    40 abcd 
 5    44    13    48    10 ac   
 6    11    42    35    27 bc   
 7    28    18    29    48 d    
 8    40    11    30    17 a    
 9    46    20    19    20 a    
10    24    40    14    43 bd   

0
投票

如果我正确地得到了这个,你想要将每一行分类为一个类,所以将类别名称作为阈值测试的连接就足够了。然后你可以使用0/1获得spread()列:

df %>% 
  mutate(
    a_ = if_else(a > 30, 'a', 'x'),
    b_ = if_else(b > 20, 'b', 'x'),
    c_ = if_else(c > 30, 'c', 'x'),
    d_ = if_else(d > 30, 'd', 'x'),
    all_ = paste0(a_, b_, c_, d_),
    one_ = 1) %>% 
  spread(all_, one_, fill = 0) %>% 
  select(-ends_with("_"))

# A tibble: 10 x 11
       a     b     c     d  abcd  axcx  axxx  xbcd  xbcx  xbxd  xxxd
   <int> <int> <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1    11    42    35    27     0     0     0     0     1     0     0
 2    21    49    46    49     0     0     0     1     0     0     0
 3    24    40    14    43     0     0     0     0     0     1     0
 4    25    36    34    36     0     0     0     1     0     0     0
 5    28    18    29    48     0     0     0     0     0     0     1
 6    40    11    30    17     0     0     1     0     0     0     0
 7    41    28    37    46     1     0     0     0     0     0     0
 8    43    31    47    40     1     0     0     0     0     0     0
 9    44    13    48    10     0     1     0     0     0     0     0
10    46    20    19    20     0     0     1     0     0     0     0

(您可以使用''而不是'x',但是spread()将覆盖您的一些原始列。)

© www.soinside.com 2019 - 2024. All rights reserved.