Вычисление среднего абсолютного значения всех числовых столбцов

Я хочу вычислить среднее абсолютное значение всех числовых столбцов для примера набора данных DT:

library(data.table)
set.seed(1)
DT <- data.table(panelID = sample(50,50),                                                    # Creates a panel ID
                      Country = c(rep("Albania",30),rep("Belarus",50), rep("Chilipepper",20)),       
                      some_NA = sample(0:5, 6),                                             
                      some_NA_factor = sample(0:5, 6),         
                      Group = c(rep(1,20),rep(2,20),rep(3,20),rep(4,20),rep(5,20)),
                      Time = rep(seq(as.Date("2010-01-03"), length=20, by="1 month") - 1,5),
                      norm = round(runif(100)/10,2),
                      Income = round(rnorm(10,-5,5),2),
                      Happiness = sample(10,10),
                      Sex = round(rnorm(10,0.75,0.3),2),
                      Age = sample(100,100),
                      Educ = round(rnorm(10,0.75,0.3),2))           
DT [, uniqueID := .I]                                                                        # Creates a unique ID     
DT[DT == 0] <- NA                                                                            # https://stackoverflow.com/questions/11036989/replace-all-0-values-to-na
DT$some_NA_factor <- factor(DT$some_NA_factor)

Я попытался вычислить средние и абсолютные средние значения следующим образом:

mean_of_differences <- DT[,lapply(Filter(is.numeric,.SD),mean, na.rm=TRUE)]
mean_of_differences <- as.data.frame(t(mean_of_differences))
mean_of_differences <- round(mean_of_differences, digits=2)
mean_of_absolute_diff <- DT[,lapply(Filter(is.numeric,.SD),function(x) mean(abs(x),na.rm=TRUE))]
mean_of_absolute_diff <- as.data.frame(t(mean_of_absolute_diff))
mean_of_absolute_diff <- round(mean_of_differences, digits=2)

Однако среднее значение дохода для абсолютных разностей отрицательное (как и для нормального среднего), что, очевидно, невозможно. Если я смотрю на свой код, я не понимаю, что делаю неправильно. Что я упускаю из виду?


person Tom    schedule 29.08.2019    source источник
comment
Абсолютные средства для меня. Однако я не запускал части с as.data.frame, хотя я не думаю, что это будет иметь значение.   -  person NelsonGon    schedule 29.08.2019
comment
Это очень странно. У меня была эта проблема с несколькими наборами данных. Есть ли альтернативный способ добиться этого, который я мог бы попробовать?   -  person Tom    schedule 29.08.2019
comment
Попробуйте это с dplyr (с DT в качестве объекта data.table): DT %>% summarise_if(is.numeric, function(x) mean(abs(x), na.rm=TRUE))   -  person NelsonGon    schedule 29.08.2019
comment
Код dplyr работает. Крайне странно (и раздражает).   -  person Tom    schedule 29.08.2019
comment
dplyr -код @NelsonGon дает то же самое, что и data.table - код Тома для меня.   -  person Jaap    schedule 29.08.2019
comment
Я переустановил R, Rstudio и все пакеты. Я все еще получаю такой результат. Также решение dplyr не работает с моим фактическим набором данных. Ребята, есть что-нибудь еще, о чем вы можете подумать?   -  person Tom    schedule 29.08.2019
comment
Я замечаю, что положительный знак меняется на отрицательный после выполнения mean_of_absolute_diff <- round(mean_of_differences, digits=2).   -  person Tom    schedule 29.08.2019
comment
@ Tom, если возможно, вы могли бы поделиться dput своего фактического набора данных.   -  person NelsonGon    schedule 29.08.2019
comment
Скопируйте и вставьте ошибку в последнюю строку :)   -  person sindri_baldur    schedule 04.09.2019


Ответы (1)


Вот решение с использованием data.table. Он (i) идентифицирует числовые столбцы и (ii) получает среднее абсолютное значение каждого числового столбца.

Данные

dt = data.table(
num1 = rnorm(100),
num2 = rnorm(100),
strv = sample(LETTERS, 100, replace = T)
)

Код

numcols = colnames(dt)[unlist(lapply(dt, is.numeric))] # Which columns are numeric?

# > numcols
# [1] "num1" "num2"

meandt = dt[, lapply(.SD, function(x) mean(abs(x))), .SDcols = numcols]
newcols = paste('mean_abs_', numcols, sep = ''); colnames(meandt) = newcols

# > meandt
#        mean_abs_num1 mean_abs_num2
# 1:     0.8287523     0.8325123
person JDG    schedule 27.09.2019