R Сводная таблица свернутых данных. - PullRequest
1 голос
/ 05 мая 2020

У меня есть такие данные, как это

    data=data.table("School"=c(1,1,1,1,1,1,0,1,0,0,1,1,1,0,1,0,1,1,1,1,1,0,0,1,0,1,1,1,1,1,1,0,1,0,1,0),
    "Grade"=c(0,1,1,1,0,0,0,1,1,1,0,1,1,0,0,1,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,0,0,0,1,0),
    "CAT"=c(1,0,1,1,0,1,0,1,1,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0,0,1,1,0,0,1,1,0,1,1,1,1),
    "FOX"=c(1,1,0,1,1,1,1,1,0,0,0,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0),
    "DOG"=c(0,0,0,1,0,0,1,0,0,1,0,1,1,1,0,1,1,0,0,1,1,0,0,1,0,1,1,0,1,0,1,1,1,0,1,1))

и wi sh, чтобы создать новую таблицу данных, например:

dataWANT=data.frame("VARIABLE"=c('CAT', 'CAT', 'CAT', 'FOX', 'FOX', 'FOX', 'DOG', 'DOG', 'DOG'),
"SCHOOL"=c(1, 1, 0, 1, 1, 0, 1, 1, 0),
"GRADE"=c(0, 1, 1, 0, 1, 1, 0, 1, 1),
"MEAN"=c(NA))

dataWANT принимает среднее значение для CAT и FOX и DOG от SCHOOL, GRADE и SCHOOL X GRADE, когда они равны 1.

Я знаю, как делать это по одному, но это не подходит для работы с большими данными.

data[, CAT1:=mean(CAT), by=list(SCHOOL)]
data[, FOX1:=mean(FOX), by=list(GRADE)]
data[, DOG1:=mean(DOG), by=list(SCHOOL, GRADE)]

data$CAT2 = unique(data[SCHOOL==1, CAT1])
data$FOX2 = unique(data[GRADE==1, FOX1])
data$DOG2 = unique(data[SCHOOL==1 & GRADE==1, DOG1])

Пожалуйста, используйте только это:

data=data.table("SCHOOL"=c(1,1,1,1,1,1,0,1,0,0,1,1,1,0,1,0,1,1,1,1,1,0,0,1,0,1,1,1,1,1,1,0,1,0,1,0),
                "GRADE"=c(0,1,1,1,0,0,0,1,1,1,0,1,1,0,0,1,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,0,0,0,1,0),
                "CAT"=c(1,0,1,1,0,1,0,1,1,0,1,0,0,1,0,1,0,0,0,0,0,0,1,0,0,1,1,0,0,1,1,0,1,1,1,1),
                "FOX"=c(1,0,0,1,1,1,1,1,0,0,0,1,1,1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,1,0,0,1,0,0,1,0),
                "DOG"=c(0,0,0,1,0,0,1,0,0,1,0,1,1,1,0,1,1,0,0,1,1,0,0,1,0,1,1,0,1,0,1,1,1,0,1,1))


data[, CAT1:=mean(CAT), by=list(SCHOOL)]
data[, CAT2:=mean(CAT), by=list(GRADE)]
data[, CAT3:=mean(CAT), by=list(SCHOOL, GRADE)]

data[, FOX1:=mean(FOX), by=list(SCHOOL)]
data[, FOX2:=mean(FOX), by=list(GRADE)]
data[, FOX3:=mean(FOX), by=list(SCHOOL, GRADE)]

data[, DOG1:=mean(DOG), by=list(SCHOOL)]
data[, DOG2:=mean(DOG), by=list(GRADE)]
data[, DOG3:=mean(DOG), by=list(SCHOOL, GRADE)]

dataWANT=data.frame("VARIABLE"=c('CAT','CAT','CAT','FOX','FOX','FOX','DOG','DOG','DOG'),
                    "TYPE"=c(1,2,3,1,2,3,1,2,3),
                    "MEAN"=c(0.48,0.44,0.428,0.6,0.611,0.6428,0.52,0.61,0.6428))

где ТИП равен 1, когда СРЕДНИЙ по оценке ШКОЛЫ,

ТИП равен 2, когда СРЕДНИЙ оценивается по GRADE,

TYPE равно 3, когда MEAN оценивается SCHOOL и GRADE

Ответы [ 3 ]

1 голос
/ 05 мая 2020

Мы могли бы использовать rbindlist после создания list, взяв MEAN после melt в наборе данных (как в другом посте)

library(data.table)
cols <- c('CAT', 'FOX', 'DOG')
data1 <- melt(data, measure.vars = cols)
list_cols <- list('SCHOOL', 'GRADE', c('SCHOOL', 'GRADE'))
lst1 <- lapply(list_cols, function(x)  
       data1[, .(MEAN = mean(value, na.rm = TRUE)), c(x, 'variable')])
rbindlist(lapply(lst1, function(x)  {
     nm1 <- setdiff(names(x), c('variable', 'MEAN'))
     x[Reduce(`&`, lapply(mget(nm1), as.logical)),
     .(VARIABLE = variable, MEAN)]}), idcol = 'TYPE')[order(VARIABLE)]
#   TYPE VARIABLE      MEAN
#1:    1      CAT 0.4800000
#2:    2      CAT 0.4444444
#3:    3      CAT 0.4285714
#4:    1      FOX 0.6000000
#5:    2      FOX 0.5555556
#6:    3      FOX 0.6428571
#7:    1      DOG 0.5200000
#8:    2      DOG 0.6111111
#9:    3      DOG 0.6428571
1 голос
/ 05 мая 2020

Вы можете подгруппировать и вычислить свои средние сначала, используя lapply(.SD,...), а затем расплавить это в своем выводе:

melt(data[School != 0 | Grade != 0, lapply(.SD, mean), by = .(School, Grade)], id.vars = c("School", "Grade"))

Добавление этого после также добавления переменной TYPE

...][, TYPE := School + (2*Grade)]

Помещение этого все вместе и убирая его тоже, он соответствует вашему желаемому результату

dataWANT <- melt(data[School != 0 | Grade != 0, lapply(.SD, mean), by = .(School, Grade)], id.vars = c("School", "Grade"))[, TYPE := School + (2*Grade)][order(variable, TYPE), .("VARIABLE" = variable, TYPE, "MEAN" = value)] 
1 голос
/ 05 мая 2020

Вы хотите получить что-то вроде этого?

library(data.table)

melt(data, measure.vars = c('CAT', 'FOX', 'DOG'))[, 
        .(MEAN = mean(value, na.rm = TRUE)), .(School, Grade, variable)]

Чтобы сгруппировать его по разным столбцам, мы можем:

cols <- c('CAT', 'FOX', 'DOG')
data1 <- melt(data, measure.vars = cols)
list_cols <- list('School', 'Grade', c('School', 'Grade'))

lapply(list_cols, function(x)  
         data1[, .(MEAN = mean(value, na.rm = TRUE)), c(x, 'variable')])
...