Программирование R: Как посчитать частоту разных значений среди всех столбцов? - PullRequest
1 голос
/ 28 февраля 2020

Я изо всех сил пытался закодировать частотный кадр данных из другого, который имеет 5 возможных значений c (0,2,3,4,5) для каждой строки, в которой значения c (2,3,4) , 5) появляются только один раз, и «0» не является уникальным, это получается из опроса предпочтений, где «5» является наиболее предпочтительным вариантом, вплоть до «2», который является менее предпочтительным (из доступных столбцов); «0» присваивается не выбранным столбцам, поэтому он повторяется.

df(c(Op1,0,5,0,0,...),

c(Op2,2,4,0,0,...),

c(Op3,0,0,5,5,...),

c(Op4,5,0,0,2,...),

c(Op5,0,0,4,0,...),

c(Op6,4,3,3,4,...),

c(Op7,3,2,2,3,...))

Каждая строка - это человек, и эти значения были пронумерованы для кластеризации этой информации, но я хотел бы подсчитать сколько «5», ..., «0» было дано всего для этих опций, что-то вроде:

///////5 / 4 / 3 / 2 / 0

Op1 / 21 / 12 / 9 / 5 / 0

Op2 / 0 / 3 / 25 / 10 / 9

Op3...

Op4...

...

Верхняя часть является заголовок и цифры ниже частоты каждого параметра в целом (для каждого человека)

Я пробовал использовать table () и count (), но count () рассчитывает для каждого параметра индивидуально, а table () не ' не считать значения, если они не отображаются, например, если у Option2 нет предпочтения с 5 оценками, он не будет отображаться как «0» и создает разные таблицы для каждого параметра, я хочу полностью интегрированный фрейм данных как показано выше.

Пожалуйста, и спасибо

Ответы [ 3 ]

2 голосов
/ 28 февраля 2020

Используя dplyr и tidyr, вы преобразуете свой фрейм данных в более длинный формат, группируете по идентификаторам OP и значениям, производите счет с использованием count и преобразуете наш фрейм данных в более широкий формат, чтобы иметь счетчик каждого значения по ОП.

Примечание: для пропущенных значений, если вы хотите, чтобы они отображались как 0, вам необходимо передать values_fill аргументы, в противном случае у вас будет несколько NA:

library(dplyr)
library(tidyr)
df %>% pivot_longer(everything(),names_to = "OP",values_to = "values") %>%
  group_by(OP,values, .drop = FALSE) %>% 
  count() %>% 
  pivot_wider(names_from = values, values_from = n, values_fill = list(n = 0)) 

# A tibble: 3 x 7
# Groups:   OP [3]
  OP      `0`   `1`   `2`   `4`   `5`   `3`
  <chr> <int> <int> <int> <int> <int> <int>
1 Op1      10     1     1     1     1     0
2 Op2      11     0     1     0     1     1
3 Op3      12     1     0     0     0     1

Воспроизводимые данные

df <- data.frame(Op1 = c(rep(0,10),sample(1:5,4)),
                   Op2 = c(rep(0,11),sample(1:5,3)),
                   Op3 = c(rep(0,12),sample(1:5,2)))
1 голос
/ 28 февраля 2020

Мы можем использовать пакет data.table для преобразования данных в длинный формат, а затем использовать функцию dcast для вычисления частоты:

dd <- data.frame(c("Op1",0,5,0,0), c("Op2",2,4,0,0), c("Op3",0,0,5,5), c("Op4",5,0,0,2), c("Op5",0,0,4,0), c("Op6",4,3,3,4), c("Op7",3,2,2,3), stringsAsFactors = FALSE)
names(dd) <- dd[1, ]
dd <- dd[-1, ]

library(data.table)
melt(setDT(dd), measure = patterns("Op"), variable = "op"
     )[, dcast(.SD, op ~ value)]

#        op     0     2     3     4     5
# 1:    Op1     3     0     0     0     1
# 2:    Op2     2     1     0     1     0
# 3:    Op3     2     0     0     0     2
# 4:    Op4     2     1     0     0     1
# 5:    Op5     3     0     0     1     0
# 6:    Op6     0     0     2     2     0
# 7:    Op7     0     2     2     0     0
1 голос
/ 28 февраля 2020

Вот решение, которое работает с предоставленными вами образцами данных, если я правильно понимаю ваш запрос:

Данные:

dd<-data.frame(c("Op1",0,5,0,0),
c("Op2",2,4,0,0),
c("Op3",0,0,5,5),
c("Op4",5,0,0,2),
c("Op5",0,0,4,0),
c("Op6",4,3,3,4),
c("Op7",3,2,2,3),stringsAsFactors = FALSE)
names(dd)<-dd[1,]
dd<-dd[-1,]

Теперь фактическое решение:

library(dplyr)
do.call(bind_rows, sapply(dd,table))

Для этого нужно применить table к каждому столбцу индивидуально, а затем использовать dplyr bind_rows, чтобы связать все вместе. bind_rows, в отличие от rbind, разделяет столбцы с разными именами. Вот как это выглядит:

# A tibble: 7 x 5
    `0`   `5`   `2`   `4`   `3`
  <int> <int> <int> <int> <int>
1     3     1    NA    NA    NA
2     2    NA     1     1    NA
3     2     2    NA    NA    NA
4     2     1     1    NA    NA
5     3    NA    NA     1    NA
6    NA    NA    NA     2     2
7    NA    NA     2    NA     2

И немного привести в порядок:

ddd<-do.call(bind_rows, sapply(dd,table))
ddd[is.na(ddd)]<-0
ddd[,order(names(ddd))]
# A tibble: 7 x 5
    `0`   `2`   `3`   `4`   `5`
  <dbl> <dbl> <dbl> <dbl> <dbl>
1     3     0     0     0     1
2     2     1     0     1     0
3     2     0     0     0     2
4     2     1     0     0     1
5     3     0     0     1     0
6     0     0     2     2     0
7     0     2     2     0     0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...