将列表分成行,同时在r中保留标识符

时间:2015-05-08 11:13:32

标签: regex r list reshape

我使用以下类型的数据集

    names<-c("Aname","Aname","Bname","Cname","Cname")
    list <- list( c('a, b','b, r','c, g'), c('d,g','e,j'),
    c('d, h','s, q','f,q'), c('d,r ','s, z'),c('d, r','d, r'))
    data<-cbind(names, list)

并希望打破列表中的每个元素,然后将其与&#34; name&#34;变量。因此,我试图制作的数据集看起来像这样:

Column 1   Column 2
Aname      a
Aname      b
Aname      b
Aname      r
Aname      c

有很多关于如何将列表转换为data.frame的讨论,但是我很难找到关于如何做到这一点的任何建议&#34;&#34;一个数据框,我希望将标识符保存在与列表相同的行上(在本例中为Names)。非常感谢!

5 个答案:

答案 0 :(得分:7)

您可以使用melt

library(reshape2)
melt(lapply(setNames(list, names), function(x)
                      unlist(strsplit(x, ', | |,'))))

答案 1 :(得分:5)

这是一个可能的基础R解决方案

myFunc <- function(x) unlist(strsplit(unlist(x), ", | |,"))

data.frame(Col1 = rep(names, sapply(list, function(x) length(myFunc(x)))), 
           Col2 = myFunc(list))

#     Col1 Col2
# 1  Aname    a
# 2  Aname    b
# 3  Aname    b
# 4  Aname    r
# 5  Aname    c
# 6  Aname    g
# 7  Aname    d
# 8  Aname    g
# 9  Aname    e
# 10 Aname    j
# 11 Bname    d
# 12 Bname    h
# 13 Bname    s
# 14 Bname    q
# 15 Bname    f
# 16 Bname    q
# 17 Cname    d
# 18 Cname    r
# 19 Cname    s
# 20 Cname    z
# 21 Cname    d
# 22 Cname    r
# 23 Cname    d
# 24 Cname    r

答案 2 :(得分:4)

使用splitstackshape的另一种方法 - 默认情况下,其cSplit函数会在分隔符旁边删除空格。

library(splitstackshape)
lengths <- sapply(data[, 2], length)
nameslist <- unlist(rep(data[, 1], lengths))
df1 <- data.frame(names = nameslist, chars = unlist(data[, 2]))
cSplit(df1, "chars", sep = ",", direction = "long")

或者根据Ananda的评论,简单地说:

cSplit(data.table(names = data[, "names"], list = sapply(data[, "list"], toString)),
 "list", ",", "long")

结果:

    names chars
 1: Aname     a
 2: Aname     b
 3: Aname     b
 4: Aname     r
 5: Aname     c
 6: Aname     g
 7: Aname     d
 8: Aname     g
 9: Aname     e
10: Aname     j
11: Bname     d
12: Bname     h
13: Bname     s
14: Bname     q
15: Bname     f
16: Bname     q
17: Cname     d
18: Cname     r
19: Cname     s
20: Cname     z
21: Cname     d
22: Cname     r
23: Cname     d
24: Cname     r

如果您不希望结果为data.table,则可以将最后一行包裹在as.data.frame()中。

答案 3 :(得分:2)

以下是使用dplyr / tidyr的方法。我们的想法是将list的每个元素转换为一个列表本身(从一个字符向量,它当前),然后调用非常有用的unnest函数

library(dplyr)
library(tidyr)
data.frame(data) %>% 
    unnest(list) %>% 
    mutate(list = strsplit(list, ",")) %>%
    unnest(list)
#   names list
#1  Aname    a
#2  Aname    b
#3  Aname    b
#4  Aname    r
#5  Aname    c
#6  Aname    g
#7  Aname    d
#8  Aname    g
#9  Aname    e
#10 Aname    j
#11 Bname    d
#12 Bname    h
#13 Bname    s
#14 Bname    q
#15 Bname    f
#16 Bname    q
#17 Cname    d
#18 Cname   r 
#19 Cname    s
#20 Cname    z
#21 Cname    d
#22 Cname    r
#23 Cname    d
#24 Cname    r

(为了摆脱额外的空间,如果需要,你可以将%>% mutate(list = gsub(" ", "", list))附加到命令链上。)

答案 4 :(得分:2)

OP将两个问题归为一类。

第一个答案是清理数据。例如,复制@ DavidArenburg的功能:

myFunc <- function(x) unlist(strsplit(unlist(x), ", | |,")) 
clean  <- sapply(list, myFunc)

第二步是叠加:

stack(setNames(clean,names))