#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’