将混合数据帧取消列出到行中。 [R

时间:2018-11-09 11:28:28

标签: r list dataframe

曾经翻遍过之前回答过的问题,但找不到与我尝试做的事情相符的事情。

这是我所拥有的简化版本:

Names = c("Andy", "Bill", "Carl", "Dave")
Letters = c("A", list(c("A", "B", "C")), list(c("B", "C")), "B")
DATA = as.data.frame(cbind(Names, Letters))

这是我想要的简化版本:

Names2 = c("Andy", rep("Bill", 3), rep("Carl", 2), "Dave")
Letters2 = c("A", "A", "B", "C", "B", "C", "B")
DATA2 = as.data.frame(cbind(Names2, Letters2))

我确定这很简单,但是我一直在努力。

欢呼

3 个答案:

答案 0 :(得分:1)

tidyr函数unnest可以为您提供帮助。 唯一的问题是DATA框架的每一列都包含一个列表向量。如果我们先将“名称”列转换为字符向量,则可以取消“字母”列表的嵌套:

Names <- c("Andy", "Bill", "Carl", "Dave")
Letters <- c("A", list(c("A", "B", "C")), list(c("B", "C")), "B")
DATA <- as.data.frame(cbind(Names, Letters))

DATA
  Names Letters
1  Andy       A
2  Bill A, B, C
3  Carl    B, C
4  Dave       B

str(DATA)
'data.frame':   4 obs. of  2 variables:
 $ Names  :List of 4
  ..$ : chr "Andy"
  ..$ : chr "Bill"
  ..$ : chr "Carl"
  ..$ : chr "Dave"
 $ Letters:List of 4
  ..$ : chr "A"
  ..$ : chr  "A" "B" "C"
  ..$ : chr  "B" "C"
  ..$ : chr "B"

所以我们转换名称

DATA %>%
  dplyr::mutate(Names = unlist(Names)) %>%
  unnest()

  Names Letters
1  Andy       A
2  Bill       A
3  Bill       B
4  Bill       C
5  Carl       B
6  Carl       C
7  Dave       B

答案 1 :(得分:0)

也许您像我一样,喜欢使用基本R功能。

do.call(
    rbind, c(apply(DATA, 1, function(x){cbind.data.frame(Names = x[1],Letters = unlist(x[2]))}),  make.row.names = FALSE)
)

#  Names Letters
#1  Andy       A
#2  Bill       A
#3  Bill       B
#4  Bill       C
#5  Carl       B
#6  Carl       C
#7  Dave       B

仅作为使用data.table的补充。

data.table::setDT(DATA)[, .(Letters = unlist(Letters)), by = .(Names = unlist(Names))]

#   Names Letters
#1:  Andy       A
#2:  Bill       A
#3:  Bill       B
#4:  Bill       C
#5:  Carl       B
#6:  Carl       C
#7:  Dave       B

答案 2 :(得分:0)

这是另一种逻辑上简单的方法。您应该制作两个向量,一个用于名称,另一个用于字母

vecName=vector()
vecLetter=vector()

现在,您应该使用外部循环遍历 DATA 中的所有名称。在内部循环中,应分隔字母并同时填充两个(vecName和vecLetter)向量。

r=1
for(i in 1:nrow(DATA))
{
  for(j in 1:length(DATA$Letters[[i]]))
  {
        vecName[r]=DATA$Names[[i]]
        vecLetter[r]=DATA$Letters[[i]][j]
        r=r+1
  }
}

最后,将两个向量组合在一起并制作另一个数据帧。

df=data.frame(vecName,vecLetter)