从类别混合的列中为每个类别构建分离的列

时间:2019-01-02 04:42:38

标签: r dplyr data-cleaning stringr

我有一个调查数据框,其中包含对三个类别的评估。我确实希望在每一列中看到对每个类别的评估,但是这样混杂在一起,

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 :(得分:2)

我们可以使用split根据列名分隔列中的值。

如果列数有限,则可以像我一样手动创建列,或者根据列的结构使用pasteseq以编程方式进行列。

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

答案 1 :(得分:0)

看起来像是要变长的堆栈,然后将其重塑为宽格式将完成此操作。这种逻辑大约有320万种变体,但这是一种:

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

答案 2 :(得分:0)

我们可以使用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))