【问题标题】:R taking list objects into tableR将列表对象放入表中
【发布时间】:2015-12-16 03:06:06
【问题描述】:

我有一个列表,里面有很多对象。我想根据这个列表的属性创建一个表。

head(casscade.list)
$`444424960908754944`
screen_name     tweet_id        tweet_created_at        retweet_screen_name
NerSeref        6.028628e+17    2015-05-25 11:44:24     Lasthowen
DURULMA_ZAMANI  6.028631e+17    2015-05-25 11:45:32     Lasthowen
ssari75         6.028647e+17    2015-05-25 11:52:10     Lasthowen   
saintserif2009  6.028672e+17    2015-05-25 12:01:48     Lasthowen
Hejinilim       6.028721e+17    2015-05-25 12:21:13     Lasthowen

$`407136916317171712`
screen_name     tweet_id        tweet_created_at        retweet_screen_name
isa_sakar       6.072663e+17    2015-06-06 15:22:18     cavurizmir
canfeda1923     6.072666e+17    2015-06-06 15:23:34     cavurizmir
Apolloniuss_58  6.072669e+17    2015-06-06 15:24:47     cavurizmir

我需要创建一个必须有这些的表;

table
retweet_screen_name screen_name         length  life(seconds)
Lasthowen           Hejinilim           5       2209
cavurizmir          Apolloniuss_58      3       149 
  • 第一行将是转发屏幕名称中的名称(因为它是重复的,其中一个就足够了),
  • 第二行将是列表对象的最后一个屏幕名称
  • 第三行将是列表对象的长度
  • 第四行将是第一个 tweet_created_at 和最后一个列表对象之间的时间差

我使用了这个功能,它解决了一半的问题

get.summary <- function(i){
        curr.frame = cascade.list[[i]]
        return(c(unique(curr.frame$retweet_screen_name),curr.frame$screen_name[nrow(curr.frame)],
                 unique(curr.frame$retweet_created_at), curr.frame$tweet_created_at[nrow(curr.frame)], 
                 nrow(curr.frame)))
}    

还有这段代码:

cdf=data.frame(t(sapply(1:length(cascade.list),get.summary)))

它创建一个数据框,所有变量都在同一行中。

 V1                                                                                     V2
c("EastanbulTimes", "onuryasercan", "2010-12-20 15:18:22", "2015-05-19 18:28:25", "1")  c("Lasthowen", "Apolloniuss_58", "2013-12-01 08:19:39", "2015-06-06 15:24:47", "3")

我需要修复数据框结构,它应该有 6 列和等于列表长度的行。我还需要添加时间变量。

提前感谢您的所有建议。

【问题讨论】:

    标签: r list dataframe rbind


    【解决方案1】:

    因为cascade.list 是具有相同列的数据框列表,您可以将它们绑定到一个数据集中,然后执行您需要的聚合。 data.table 的实现:

    # make a list of the dataframes (see below for the used dataframes)
    dflist <- list(df1,df2)
    # bind the dataframes together into one datatable (which is an enhanced dataframe)
    library(data.table)
    DT <- rbindlist(dflist)
    

    使用生成的数据表,您现在可以执行所需的汇总,如下所示:

    DT[, .(screen_name = screen_name[.N],
           length = .N,
           life_in_seconds = difftime(tweet_created_at[.N], tweet_created_at[1], units="secs")),
       by = .(retweet_screen_name)]
    

    导致:

       retweet_screen_name    screen_name length life_in_seconds
    1:           Lasthowen      Hejinilim      5       2209 secs
    2:          cavurizmir Apolloniuss_58      3        149 secs
    

    解释:

    • .N 是一个特殊的 data.table 运算符,它为您提供组中的总行数(或未使用分组时的 data.table)。
    • screen_name[.N] 将为您提供最后一个 screen_name,因为它使用总行数进行索引,从而为您提供每个组的最后一次观察。同样,screen_name[1] 会为您提供每组中的第一个观察结果。
    • difftime 或多或少不言自明。使用units,您可以指定时差的表达方式。有关可能性,请参阅?difftime
    • 使用by =,您可以指定应使用哪些列来确定数据的分组。

    类似的操作可以用dplyr:

    library(dplyr)
    
    newdf <- bind_rows(dflist)
    
    newdf %>% group_by(retweet_screen_name) %>% 
      summarise(screen_name = last(screen_name),
                length = n(),
                life_in_seconds = difftime(last(tweet_created_at), first(tweet_created_at), units="secs"))
    

    使用的数据:

    df1 <- structure(list(screen_name = structure(c(3L, 1L, 5L, 4L, 2L), .Label = c("DURULMA_ZAMANI", "Hejinilim", "NerSeref", "saintserif2009", "ssari75"), class = "factor"), tweet_id = c(6.028628e+17, 6.028631e+17, 6.028647e+17, 6.028672e+17, 6.028721e+17), tweet_created_at = structure(c(1432547064, 1432547132, 1432547530, 1432548108, 1432549273), class = c("POSIXct", "POSIXt"), tzone = ""), retweet_screen_name = structure(c(1L, 1L, 1L, 1L, 1L), .Label = "Lasthowen", class = "factor")), .Names = c("screen_name", "tweet_id", "tweet_created_at", "retweet_screen_name"), class = "data.frame", row.names = c(NA, -5L))
    df2 <- structure(list(screen_name = structure(c(3L, 2L, 1L), .Label = c("Apolloniuss_58", "canfeda1923", "isa_sakar"), class = "factor"), tweet_id = c(6.072663e+17, 6.072666e+17, 6.072669e+17), tweet_created_at = structure(c(1433596938, 1433597014, 1433597087), class = c("POSIXct", "POSIXt"), tzone = ""), retweet_screen_name = structure(c(1L, 1L, 1L), .Label = "cavurizmir", class = "factor")), .Names = c("screen_name", "tweet_id", "tweet_created_at", "retweet_screen_name"), class = "data.frame", row.names = c(NA, -3L))
    

    【讨论】:

    • 嗨 Jaap,我使用了两个选项,它们给出了不同的结果,例如 data.table 选项有 43,314 行,dplyr 在表中有 43,334 行。 dplyr 的结果具有与级联列表对象中相同的数字的正确数字。我只是想知道你对此有什么想法吗?谢谢。 PS:我使用了tweet_id_str,它是一个唯一的整数来分隔数据。
    • @eabanoz 不幸的是,如果没有数据,很难说差异来自哪里。
    • 嗨 Jaap,我想问一下有没有办法将日期差异保持为 Posixct 或日期。我尝试将 difftime 转换为其他格式,但没有成功。
    • @eabanoz POSIXctDate 都是日期时间组合,因此不适合您的变量。最好转换为数值变量:DT[, life_in_seconds:=as.numeric(life_in_seconds)]
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-21
    • 2014-10-15
    • 2021-02-25
    • 2018-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多