【问题标题】:Apply if else statements across columns in data frame based on condition of value in other column根据其他列中的值条件跨数据框中的列应用 if else 语句
【发布时间】:2017-06-25 12:37:32
【问题描述】:

我想对数据框中的每一列 (a-d) 应用 if else 语句,如果每个值满足基于另一列 (m) 的条件,则值保持不变,否则将值更改为零。

这是一个可重现的例子:

a <- c(10, 11, 12, 15,7,8)
b <- c(15,11,16,17,1.5,9)
c <- c(18,14,6,14,1,17)
d <- c(12,11,13,19,2,4)
p <- c(2,1,3,2.5,1.3,2.1)
m <- c(12,13,8,9,14,11)

df<- data.frame(a,b,c,d,p,m)

print(df)

   a    b  c  d   p  m
1 10 15.0 18 12 2.0 12
2 11 11.0 14 11 1.0 13
3 12 16.0  6 13 3.0  8
4 15 17.0 14 19 2.5  9
5  7  1.5  1  2 1.3 14
6  8  9.0 17  4 2.1 11

这是我想做的“长”版本,它有效但非常重复:

df$a<- ifelse((df$a-df$p)>df$m, df$a, 0)
df$b<- ifelse((df$b-df$p)>df$m, df$b, 0)
df$c<- ifelse((df$c-df$p)>df$m, df$c, 0)
df$d<- ifelse((df$d-df$p)>df$m, df$d, 0)

print(df)

这是我想要的输出:

   a  b  c  d   p  m
1  0 15 18  0 2.0 12
2 11 11 14 11 1.0  7
3 12 16  0 13 3.0  8
4 15 17 14 19 2.5  9
5  0  0  0  0 1.3 14
6  0  0 17  0 2.1 11

【问题讨论】:

    标签: r if-statement dataframe lapply


    【解决方案1】:

    我们可以使用lapply

    df[1:4] <- lapply(df[1:4], function(x) ifelse((x - df$p) > df$m, x, 0))
    df
    #   a  b  c  d   p  m
    #1  0 15 18  0 2.0 12
    #2  0  0  0  0 1.0 13
    #3 12 16  0 13 3.0  8
    #4 15 17 14 19 2.5  9
    #5  0  0  0  0 1.3 14
    #6  0  0 17  0 2.1 11
    

    或者不使用ifelse

    df[1:4] <- ((df[1:4]-df$p) > df$m)*df[1:4]
    

    【讨论】:

    • 完美运行,认为它与索引有关。非常感谢@akrun
    【解决方案2】:

    通过一些逻辑矩阵子集和常规子集,你可以做到

    df[, 1:4][df[,1:4] - df$p <= df$m] <- 0
    df
       a  b  c  d   p  m
    1  0 15 18  0 2.0 12
    2  0  0  0  0 1.0 13
    3 12 16  0 13 3.0  8
    4 15 17 14 19 2.5  9
    5  0  0  0  0 1.3 14
    6  0  0 17  0 2.1 11
    

    第一个[ 对可能填充的列进行子集化,第二个[ 对这些列执行逻辑测试并返回一个逻辑矩阵,指示要填充矩阵中的哪些元素。

    【讨论】:

      猜你喜欢
      • 2017-07-03
      • 2011-08-15
      • 1970-01-01
      • 2022-12-08
      • 2017-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多