对于列Y中每行的长度,在列X中复制行

时间:2014-04-22 11:19:26

标签: r dataframe

(请随意将标题调整为更贴合的东西)

我有一个data.frame,其中有两列,XYlist,如下所示

X <- list("A","B","C","D")
Y <- list("a",c("a", "b"),"c",c("a", "c", "d"))

df <- as.data.frame(cbind(X,Y))

当列Y有两个或更多条目或此处为字符时,我希望Y中每行的长度(字符数)对应列中相同行的数量X。更轻松,对于Y中的每个字符,它们必须是X中的单个行。

# desired output

X Y
A a
B a
B b
C c
D a
D c
D d

我不知道该怎么做,所以任何指针都会受到赞赏,谢谢!

2 个答案:

答案 0 :(得分:3)

尝试

do.call(rbind, Map(expand.grid, X, Y))
##   Var1 Var2
## 1    A    a
## 2    B    a
## 3    B    b
## 4    C    c
## 5    D    a
## 6    D    c
## 7    D    d

答案 1 :(得分:1)

这是另一种选择:

library(data.table)
DT <- as.data.table(df)
DT[, list(Y = unlist(Y)), by = unlist(X)]
#    unlist Y
# 1:      A a
# 2:      B a
# 3:      B b
# 4:      C c
# 5:      D a
# 6:      D c
# 7:      D d

这比Map + expand.grid方法快得多,即使您只处理1000行;但是,如果每个&#34; row&#34; &#34; X&#34;只有一个元素。


这是一个应该能够处理多个列中包含多个元素的列表的函数,并且应该可以非常轻松地处理两个以上的列。

egFun <- function(indf) {
  DT <- data.table(indf, keep.rownames=TRUE, key = "rn")
  out <- Reduce(function(x, y) x[y, allow.cartesian = TRUE], 
         lapply(setdiff(names(DT), "rn"), function(x) 
           DT[, list(unlist(get(x))), by = rn]))
  setnames(out, names(DT))
  out
}

用法是:

egFun(df)