Как повторить суммирование столбца на основе нескольких других групп столбцов - PullRequest
1 голос
/ 03 июня 2019

Допустим, я хочу вычислить среднее значение (или пользовательскую функцию) для столбца A на основе различных значений в столбцах BD.Вот данные:

input:
data <- data.frame(A = round(runif(20,min = 0,max = 10),0),
                   B = round(runif(20,min = 0,max = 1),0),
                   C = round(runif(20,min = 0,max = 1),0),
                   D = round(runif(20,min = 0,max = 1),0))

output (note your rand numbers might result in different summary table):
col value mean    
B   0     5.92
B   1     4.71
C   0     6   
C   1     5.17
D   0     4.89
D   1     6

Я могу сделать это для каждого столбца отдельно:

data %>% group_by(B) %>% summarise(mean(A))

Я положил в for loop:

p <- data.frame(NULL)
for(i in c('B','C','D')){
  q <- data %>% group_by_(i) %>% summarise(col=i,mean = mean(A))
  p <- append(p,q)
}

но это не сработало так, как ожидалось.Любые предложения будут очень полезны.

Ответы [ 2 ]

1 голос
/ 03 июня 2019

Другой вариант, использующий базу и пакет изменения формы, будет:

data <- data.frame(A = round(runif(20,min = 0,max = 10),0),
                   B = round(runif(20,min = 0,max = 1),0),
                   C = round(runif(20,min = 0,max = 1),0),
                   D = round(runif(20,min = 0,max = 1),0))

melt(t(apply(data[,-1],2,function(x) by(data[,1],x,mean))))

  Var1 Var2    value
1    B    0 4.100000
2    C    0 3.727273
3    D    0 4.250000
4    B    1 4.800000
5    C    1 5.333333
6    D    1 4.583333

функции плавления и t предназначены только для получения результата в нужной форме

1 голос
/ 03 июня 2019

Можно указать gather данные в формате 'long', сгруппированные по столбцам 'key', 'val', получить mean из 'A'

library(tidyverse)
gather(data, key, val, B:D) %>%
     group_by(key, val) %>%
     summarise(A = mean(A))

Или в base R, путем unlist перевода столбцов из «B» в «D» и использования группирующего столбца в качестве «A» с реплицированными именами столбцов

aggregate(A ~ ., cbind(data['A'], cN = names(data)[-1][col(data[-1])], 
           group = unlist(data[-1])), mean)

data

set.seed(24)
data <- data.frame(A = round(runif(20,min = 0,max = 10),0),
               B = round(runif(20,min = 0,max = 1),0),
               C = round(runif(20,min = 0,max = 1),0),
               D = round(runif(20,min = 0,max = 1),0))
...