Примените две разные формулы к четырем столбцам фрейма данных - PullRequest
0 голосов
/ 24 декабря 2018

Я хочу применить две разные формулы к четырем столбцам моего кадра данных 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 голосов
/ 24 декабря 2018

Если ваша цель - применить две функции к чередующимся столбцам, то вы можете сделать это с помощью логического индексирования

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
0 голосов
/ 24 декабря 2018

Мы можем использовать mutate_at от dplyr

library(dplyr)
df1 %>%
    mutate_at(vars(B, D), formula_1) %>%
    mutate_at(vars(A, C), formula_2)
0 голосов
/ 24 декабря 2018

РЕДАКТИРОВАТЬ

Поскольку существуют некоторые значения NA s и 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))
...