在四个数据框列上应用两个不同的公式

Apply two different formulas on four data frame columns

我想在数据框 df 的四列上应用两个不同的公式。我已手动完成此操作,但由于我的原始数据框有多个列,因此我希望能够使用循环或 case when 来更快地执行此操作。

示例数据框 df 如下所示:

A   B   C  D
20  100 4  1200
40  150 6  2300 
34  200 3  1230
32  225 9  1100
12  220 10 1000

公式 1:

(x-max(x))/(max(x)-min(x))

公式 2:

(min(x)-x)/(max(x)-min(x))

我想在 B 和 D 列上应用公式 1,在 A 和 C 列上应用公式 2。

应用公式后,我想将值存储在不同的数据框中但具有相同的列名。

这是我所做的:

formula_1 <-function(x) {
  (((x - min(x)))/(max(x) - min(x))) 
}

    formula_2 <-function(x){(min(x)-x)/(max(x)-min(x))
}

Create an empty dataframe BI_score
BI_score$B <- formula_1(df$B)
BI_score$D <- formula_1 (df$D)
BI_score$A <- formula_2 (df$A)
BI_score$C <- formula_2 (df$C)    

编辑

因为有一些 NAs 和 Inf 值,如果我们想从计算中排除它们,我们可以通过如下更新函数来处理它,然后将函数应用于列作为之前显示。

formula_1 <-function(x) {
   temp <- x[is.finite(x)]
   replace(x, is.finite(x), (((temp - min(temp)))/(max(temp) - min(temp))))
}

formula_2 <-function(x) {
   temp <- x[is.finite(x)]
   replace(x, is.finite(x), (min(temp)-temp)/(max(temp)-min(temp)))
}

最直接的方法是使用 lapply 在选定的列上单独应用函数。

BI_score <- df
fm1_cols <- c("B", "D")
fm2_cols <- c("A", "C")
BI_score[fm1_cols] <- lapply(df[fm1_cols], formula_1)
BI_score[fm2_cols] <- lapply(df[fm2_cols], formula_2)


BI_score
#      A    B     C     D
#1 -0.29 0.00 -0.14 0.154
#2 -1.00 0.40 -0.43 1.000
#3 -0.79 0.80  0.00 0.177
#4 -0.71 1.00 -0.86 0.077
#5  0.00 0.96 -1.00 0.000

如@Sotos 所述,如果您想在交替列上应用该函数,您可以这样做

BI_score[c(TRUE, FALSE)] <- lapply(df[c(TRUE, FALSE)], formula_1)
BI_score[c(FALSE, TRUE)] <- lapply(df[c(FALSE, TRUE)], formula_2)

纯属娱乐,方法使用dplyr

library(dplyr)

bind_cols(df %>% select(fm1_cols) %>% mutate_all(formula_1), 
          df %>% select(fm2_cols) %>% mutate_all(formula_2))

如果您的目标是在交替列上应用这两个函数,那么您可以通过逻辑索引来实现

cbind.data.frame(sapply(df[c(TRUE, FALSE)], formula_2),  
                 sapply(df[c(FALSE, TRUE)], formula_1))


#           A          C    B          D
#1 -0.2857143 -0.1428571 0.00 0.15384615
#2 -1.0000000 -0.4285714 0.40 1.00000000
#3 -0.7857143  0.0000000 0.80 0.17692308
#4 -0.7142857 -0.8571429 1.00 0.07692308
#5  0.0000000 -1.0000000 0.96 0.00000000

我们可以使用 mutate_at 来自 dplyr

library(dplyr)
df1 %>%
    mutate_at(vars(B, D), formula_1) %>%
    mutate_at(vars(A, C), formula_2)