Построение отдельных столбцов для каждой категории из столбцов, в которых категории смешаны - PullRequest
0 голосов
/ 02 января 2019

У меня есть фрейм данных опроса, который содержит оценки трех категорий.Я хочу видеть оценки каждой категории в каждом столбце, но она выглядит следующим образом:

ID  q1 q2 q3 q4 q5 q6
1   c2 e1 c1 e1 c3 e2
2   c1 e1 c3 e2 c2 e0
3   c3 e0 c2 e2 c1 e1

Что я хочу получить:

ID  c1 c2 c3
1   e1 e1 e2
2   e1 e0 e2
3   e1 e2 e0

Однако, пробуя несколько способов черезstringr и dplyr, теперь я просто застрял здесь:

ID  a1    a2    a3
1   c1-e1 c2-e1 c3-e2
2   c1-e1 c2-e0 c3-e2
3   c1-e1 c2-e2 c3-e0

Есть ли кто-нибудь, кто знает, как решить эту проблему?Заранее спасибо!

Ответы [ 3 ]

0 голосов
/ 02 января 2019

Похоже, что стек длинным, и тогда изменение формы в широкоформатный будет выполнено. Существует около 3,2 миллиона вариантов этой логики, но вот одна:

tmp <- reshape(dat, idvar="ID", varying=list(c(2,4,6),c(3,5,7)),
               v.names=c("name","value"), direction="long", timevar=NULL)

#    ID name value
#1.1  1   c2    e1
#2.1  2   c1    e1
#3.1  3   c3    e0
#1.2  1   c1    e1
#2.2  2   c3    e2
#3.2  3   c2    e2
#1.3  1   c3    e2
#2.3  2   c2    e0
#3.3  3   c1    e1

Этот длинный формат может даже использоваться для целей моделирования. Если вам определенно требуется широкий формат, измените форму снова:

reshape(tmp, idvar="ID", timevar="name", direction="wide")

#    ID value.c2 value.c1 value.c3
#1.1  1       e1       e1       e2
#2.1  2       e0       e1       e2
#3.1  3       e2       e1       e0
0 голосов
/ 02 января 2019

Мы можем использовать melt/dcast из data.table

library(data.table)
dcast(melt(setDT(df1), measure = patterns('^q[135]', '^q[246]')),
           ID ~ value1, value.var = 'value2')
#    ID c1 c2 c3
#1:  1 e1 e1 e2
#2:  2 e1 e0 e2
#3:  3 e1 e2 e0

данные

df1 <- structure(list(ID = 1:3, q1 = c("c2", "c1", "c3"), q2 = c("e1", 
"e1", "e0"), q3 = c("c1", "c3", "c2"), q4 = c("e1", "e2", "e2"
 ), q5 = c("c3", "c2", "c1"), q6 = c("e2", "e0", "e1")), 
class = "data.frame", row.names = c(NA, -3L))
0 голосов
/ 02 января 2019

Мы могли бы использовать split для разделения значений в столбце на основе имен столбцов.

Если у вас есть ограниченные столбцы, вы можете вручную создавать столбцы (как я) или делать это программно, используя paste и seq в соответствии со структурой ваших столбцов.

cols <- c("q1", "q3", "q5")
vals <- c("q2", "q4", "q6")
do.call("cbind.data.frame", split(unlist(df[vals]), unlist(df[cols])))

#    c1 c2 c3
#q22 e1 e1 e0
#q41 e1 e2 e2
#q63 e1 e0 e2

Вы можете cbind первый столбец, чтобы получить ID столбец обратно.

cbind(df[1], do.call("cbind.data.frame", split(unlist(df[vals]), unlist(df[cols]))))

#    ID c1 c2 c3
#q22  1 e1 e1 e0
#q41  2 e1 e2 e2
#q63  3 e1 e0 e2

Как упомянул @Farah Nazifa, если мы хотим поддерживать порядок строк также для каждого столбца, мы можем использовать mapply следующим образом.

col_values <- unlist(df[cols])
data.frame(mapply(function(x, y) x[y], 
    split(unlist(df[vals]), col_values), split(row(df[vals]), col_values)))

#    c1 c2 c3
#q41 e1 e1 e2
#q22 e1 e0 e2
#q63 e1 e2 e0
...