将条件函数应用于数据框

我想将函数应用于数据帧的行 . 该函数的条件是一列的值大于另一列中的值 . 如果满足条件,我从两个(其他)列中取出元素并将它们相乘,然后将结果添加到新列中 . 如果不满足初始条件,则不存在乘法,并将原始值复制到新列 .

创建一些数据:

var0 <- c("A", "B", "C", "D", "E")
var1 <- rep(c(105,200), each = 5)
var2 <- c(110:114, 25:29)
var3 <- rep(c(560,135), each = 5)
var4 <- rep(c(0.5,0.2), each = 5)
my_df <- as.data.frame(cbind(var0, var1, var2, var3, var4))

看看数据:

var0 var1 var2 var3 var4
    1     A  105  110  560  0.5
    2     B  105  111  560  0.5
    3     C  105  112  560  0.5
    4     D  105  113  560  0.5
    5     E  105  114  560  0.5
    6     A  200   25  135  0.2
    7     B  200   26  135  0.2
    8     C  200   27  135  0.2
    9     D  200   28  135  0.2
    10    E  200   29  135  0.2

我尝试编写代码:

apply(my_df, 1, function(x) {
  if(x$var3 > x$var1) {
    x$output <- x$var2 * x$var4
    } else {
      x$output <- x$var2
    }
      return(x)
  })

结果应该是什么样子:

var0 var1 var2 var3 var4 output
    1     A  105  110  560  0.5   55.0
    2     B  105  111  560  0.5   55.5
    3     C  105  112  560  0.5   56.0
    4     D  105  113  560  0.5   56.5
    5     E  105  114  560  0.5   57.0
    6     A  200   25  135  0.2   25.0
    7     B  200   26  135  0.2   26.0
    8     C  200   27  135  0.2   27.0
    9     D  200   28  135  0.2   28.0
    10    E  200   29  135  0.2   29.0

由于var3在前5行中大于var1,因此var2 * var4出现,在最后5行中不满足条件,因此var2只是复制到输出列 .

回答(2)

2 years ago

你不需要在这里使用 apply() 函数,你可以只使用 ifelse()

df$output <- ifelse(df$var3 > df$var1, df$var2*df$var4, df$var2)

2 years ago

var0 <- c("A", "B", "C", "D", "E")
var1 <- rep(c(105,200), each = 5)
var2 <- c(110:114, 25:29)
var3 <- rep(560,135, 5)
var4 <- rep(c(0.5,0.2), each = 5)

避免数字转换为我正在使用cbind.data.frame而不是cbind的as.data.frame的因素

my_df <-cbind.data.frame(var0, var1, var2, var3, var4)

> str(my_df)
'data.frame':   10 obs. of  5 variables:
 $ var0: Factor w/ 5 levels "A","B","C","D",..: 1 2 3 4 5 1 2 3 4 5
 $ var1: num  105 105 105 105 105 200 200 200 200 200
 $ var2: int  110 111 112 113 114 25 26 27 28 29
 $ var3: num  560 560 560 560 560 560 560 560 560 560
 $ var4: num  0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2

然后我使用ifelse条件来获取新列

>my_df$output=ifelse(my_df$var3>my_df$var1,my_df$var2*my_df$var4,my_df$var2)
> my_df
   var0 var1 var2 var3 var4 output
1     A  105  110  560  0.5   55.0
2     B  105  111  560  0.5   55.5
3     C  105  112  560  0.5   56.0
4     D  105  113  560  0.5   56.5
5     E  105  114  560  0.5   57.0
6     A  200   25  560  0.2    5.0
7     B  200   26  560  0.2    5.2
8     C  200   27  560  0.2    5.4
9     D  200   28  560  0.2    5.6
10    E  200   29  560  0.2    5.8

Note 我在var3中没有得到与你相同的值 . 所以我把var3变成了给定的

> var3 <- c(rep(560,5),rep(135,5))

> var3
 [1] 560 560 560 560 560 135 135 135 135 135
>  my_df <-cbind.data.frame(var0, var1, var2, var3, var4)
>  my_df$output=ifelse(my_df$var3>my_df$var1,my_df$var2*my_df$var4,my_df$var2)
> my_df
   var0 var1 var2 var3 var4 output
1     A  105  110  560  0.5   55.0
2     B  105  111  560  0.5   55.5
3     C  105  112  560  0.5   56.0
4     D  105  113  560  0.5   56.5
5     E  105  114  560  0.5   57.0
6     A  200   25  135  0.2   25.0
7     B  200   26  135  0.2   26.0
8     C  200   27  135  0.2   27.0
9     D  200   28  135  0.2   28.0
10    E  200   29  135  0.2   29.0