曾经翻遍过之前回答过的问题,但找不到与我尝试做的事情相符的事情。
这是我所拥有的简化版本:
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))
我确定这很简单,但是我一直在努力。
欢呼
答案 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)