Как применить функцию к одному столбцу из dataframe и вернуть исходный датафрейм но с измененным столбцом

Как применить функцию к одному столбцу в dataframe, а не ко всем столбцам, и затем вернуть исходный датафрейм с измененным столбцом?

Пример: есть датафрейм

    X1   X2   X3   X4
1  8.5  9.7 10.7 10.3
2  8.1 12.8  9.7 12.6
3  9.6  7.4  8.4 12.7
4  9.6 10.9  7.7  8.0
5 11.9 13.7 12.3 11.0

Необходимо в одном столбце (например, X1) вычислить среднее значение, затем отнять от каждого значения в данном столбце полученное среднее, и вернуть исходный датафрейм с одним измененным столбцом.

Пробовал через sapply

sapply (test_data[var_names] , function (x) {x-mean(x)} )

здесь:

  • test_data - датафрейм указанный выше
  • var_names - вектор с именем (именами) столбцов в датафрейме, в котором надо найти среднее и отнять его от каждого значения в столбце.

Но результат возвращает только изменённые столбцы. А необходимо вернуть исходный датафрейм с измененным (измененными) столбцом (столбцами).


Ответы (4 шт):

Автор решения: Дима Мандрик

"Но результат возвращает только изменённые столбцы"

Маловероятно, но спросить стоит: пробовали df$столбец (или df[,c('столбец1','столбец2')] = повторить то, "что возвращает измененные столбцы"?

→ Ссылка
Автор решения: vldminkov
require(dplyr)
require(magrittr)
mutate(df, X1_1 = (X1 - mean(X1))) %>% 
select(c(X1_1, X2, X3, X4))-> df1

Вариант 2

require(bplyr)
b_mutate(df, X1_1 = (X1 - mean(X1))) ->.;
b_select(., c(X1_1, X2, X3, X4))-> df1
→ Ссылка
Автор решения: intravizor

Всем спасибо! Решил задачу. Код:

X1<-c(8.5,8.1,9.6,9.6,11.9)
X2<-c(9.7,12.8,7.4,10.9,13.7)
X3<-c(10.7,9.7,8.4,7.7,12.3)
X4<-c(10.3,12.6,12.7,8.0,11.0)
test_data <- data.frame (X1, X2, X3, X4) 
centered <- function(test_data, var_names){
test_data1<-as.data.frame (sapply (test_data[var_names] , function (x) {x-mean(x)} )) 
test_data[var_names] <-list(NULL) 
df<-cbind(test_data, test_data1)
df[, order(colnames (df))] 
}
var_names = c("X1", "X4")
centered(test_data, var_names)
→ Ссылка
Автор решения: Ogurtsov

Можно использовать пакет data.table с его in-place изменением объектов:

> library(data.table)
> dt <- data.table(a = 1:5, b = 1:5)
> dt
   a b
1: 1 1
2: 2 2
3: 3 3
4: 4 4
5: 5 5
> dt[, a := a - mean(a)]
> dt
    a b
1: -2 1
2: -1 2
3:  0 3
4:  1 4
5:  2 5
→ Ссылка