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

时间:2018-12-24 10:05:59

标签: r loops case-when

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

这是示例数据帧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))

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

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

这就是我所做的:

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)    

3 个答案:

答案 0 :(得分:4)

编辑

由于存在一些NAInf值,如果我们要从计算中排除它们,我们可以通过更新如下函数来处理它,然后将函数应用于列,如上所示

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))

答案 1 :(得分:3)

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

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

答案 2 :(得分:3)

我们可以使用mutate_at中的dplyr

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