在R中将不同长度的命名向量合并到数据帧(保留名称信息作为列名)的快速方法

时间:2014-11-27 12:26:37

标签: r merge

我有一个名为vector的列表L.例如,第一个元素:

> L[[1]]
$event
[1] "EventA"

$time
[1] "1416355303"

$city
[1] "Los Angeles"

$region
[1] "California"

$Locale
[1] "en-GB"

当我unlist列表中的每个元素时,生成的向量看起来像这样(对于前3个元素):

> unlist(L[[1]])
    event          time          city        region        Locale 
 "EventA"  "1416355303" "Los Angeles"  "California"       "en-GB" 

> unlist(L[[2]])
   event         time       Locale 
"EventB" "1416417567"      "en-GB" 

> unlist(L[[3]])
   event properties.time 
 "EventM"    "1416417569" 

我在列表中有超过50万个元素,每个元素最多有42个这些特征/名称。我必须将它们合并到一个考虑了它们名称的数据框中,并且并非所有这些都具有相同数量的特征或名称(在上面的示例中,V2没有regioncity的信息) 。目前,我所做的是遍历整个列表的循环:

df1 <- merge(stack(unlist(L[[1]])), stack(unlist(L[[2]])),
        by = "ind", all = TRUE)
suppressWarnings(for (i in 3:length(L)){
    df1 <- merge(df1, stack(unlist(L[[i]])), by = "ind", all = TRUE)
})
df1 <- as.data.frame(t(df1))

对于上面的示例,它返回:

                 V1     V2     V3         V4         V5
 ind             city  event Locale     region       time
 values.x Los Angeles EventA  en-GB California 1416355303
 values.y        <NA> EventB  en-GB       <NA> 1416417567
 values          <NA> EventM   <NA>       <NA> 1416417569

这就是我想要的。但是,请记住列表的长度以及每次执行该命令的事实:

df1 <- merge(df1, stack(unlist(L[[i]])), by = "ind", all = TRUE)

运行,加载整个数据帧(df1),循环需要很长时间。因此,我想知道是否有人知道更好/更快的编码方式。换一种说法。给定一长串具有不同长度的命名向量,有一种快速的方法将它们合并到如上所述的数据帧中。

例如,有没有办法使用foreach%dopar%执行此操作?无论如何,欢迎任何更快的方法。

3 个答案:

答案 0 :(得分:3)

我听说data.table包非常快。 rbindlist非常适合此列表。

library(data.table)
rbindlist(L, fill=TRUE)
#     event       time        city     region Locale
# 1: EventA 1416355303 Los Angeles California  en-GB
# 2: EventB 1416417567          NA         NA  en-GB
# 3: EventM 1416417569          NA         NA     NA

答案 1 :(得分:2)

我不确定你为什么使用merge。在我看来,你应该只是rbind

L <- list(list(event = "EventA", time = 1416355303, 
               city = "Los Angeles", region = "California",
               Locale = "en-GB"),
          list(event = "EventB", time = 1416417567,
               Locale = "en-GB"),
          list(event = "EventM", time = 1416417569))

library(plyr)
do.call(rbind.fill, lapply(L, as.data.frame))
#   event       time        city     region Locale
#1 EventA 1416355303 Los Angeles California  en-GB
#2 EventB 1416417567        <NA>       <NA>  en-GB
#3 EventM 1416417569        <NA>       <NA>   <NA>

答案 2 :(得分:2)

这是一个需要考虑的紧凑型解决方案:

library(reshape2)
dcast(melt(L), L1 ~ L2, value.var = "value")
#   L1        city  event Locale     region       time
# 1  1 Los Angeles EventA  en-GB California 1416355303
# 2  2        <NA> EventB  en-GB       <NA> 1416417567
# 3  3        <NA> EventM   <NA>       <NA> 1416417569