фиксировать частоту шаблона столбца

#r #dplyr #transform #frequency #reshape2

#r #dplyr #преобразовать #частота #изменение формы 2

Вопрос:

У меня есть набор данных, подобный приведенному ниже

 Id        A      B       C
10        1      0       1
11        1      0       1
12        1      1       0
13        1      0       0
14        0      1       1
  

Я пытаюсь подсчитать шаблоны столбцов, подобные приведенному ниже.

  Pattern         Count
 A, C            2
 A, B            1
 A               1
 B, C            1
  

Не уверен, с чего начать, любая помощь или совет приветствуются.

Комментарии:

1. @Ty Voss тебе нужна сумма этих столбцов на основе идентификатора

2. Вы отметили это с помощью dplyr , так что, вероятно, вы могли бы также сделать df %>% gather(variable, value, -Id) %>% group_by(Id) %>% summarise(res = toString(variable[value == 1])) %>% count(res)

3. @Arunkumarmahesh, Арун, идентификатор здесь не имеет значения. Хороший сложный вопрос.

Ответ №1:

Если вам не нужно группировать по идентификатору, тогда просто,

 table(apply(df[-1], 1, function(i) paste(names(i[i == 1]), collapse = ',')))

#  A A,B A,C B,C 
#  1   1   2   1 
  

Комментарии:

1. Вероятно, вы могли бы немного улучшить это, преобразовав в логическую матрицу за пределами apply , что-то вроде apply(df[-1] == 1, 1, function(i) toString(names(i[i])))

Ответ №2:

Начнем с «обратного» табулирования данных в двух отдельных векторах:

 w = which(dat[-1] == 1L, TRUE)
  

мы могли бы использовать

 table(tapply(names(dat)[-1][w[, "col"]], w[, "row"], paste, collapse = ", "))
#
#   A A, B A, C B, C 
#   1    1    2    1
  

Если результат нужен не только для целей форматирования, чтобы избежать ненужного paste / strsplit , альтернативой — среди многих — является:

 pats = split(names(dat)[-1][w[, "col"]], w[, "row"])
upats = unique(pats)
data.frame(pat = upats, n = tabulate(match(pats, upats)))
#   pat n
#1 A, C 2
#3 A, B 1
#4    A 1
#5 B, C 1
  

Комментарии:

1. это сработало идеально. , я использовал as.data.frame , и ему не нужно было использовать эти последние три разделенных, уникальных и т.д..

Ответ №3:

Мы можем попробовать с

 table(gsub(",*N|N,*", "", chartr('0123', 'NABC', 
         do.call(paste, c(df1[-1] * col(df1[-1]), sep=",")))))

#  A A,B A,C B,C 
#  1   1   2   1 
  

Как упоминал @DavidArenburg, old/new ввод chartr может быть выполнен автоматически с помощью

 cols <- paste(c("N", names(df1[-1])), collapse = "") 
indx <- paste(seq(nchar(cols)) - 1, collapse = "")
table(gsub(",*N|N,*", "", chartr(indx, cols, 
      do.call(paste, c(df1[-1] * col(df1[-1]), sep=",")))))
  

Комментарии:

1. Это очень приятно, хотя и не настолько общее, возможно, используйте что-то вроде cols <- paste(c("N", names(df[-1])), collapse = "") ; indx <- paste(seq(nchar(cols)) - 1, collapse = "") внутри chartr вместо просто ‘0123’ и ‘NABC’