使用lapply对R

时间:2016-08-20 13:57:54

标签: r list dataframe element lapply

我目前有一个包含150个元素的列表,每个元素包含5列,每行200-1000行不等。我想在数据框的列表中的每个元素内执行拆分。我本质上想要创建一个相同长度的新列表,但列表中的数据帧非常不同。我知道我想对每个元素做什么,但似乎无法在整个列表中找到正确的方法来实现它。下面是一个示例列表:

>ex

$`66th & Center`

    Bike CheckoutKioskName ReturnKioskName  Checkout_date_time    Return_date_time    UserRole
24583  191     66th & Center   66th & Center 2013-02-28 15:08:58 2013-02-28 15:09:08 Maintenance
24584  191     66th & Center   66th & Center 2013-02-28 15:09:30 2013-02-28 15:09:54 Maintenance
24585  191     66th & Center   66th & Center 2013-02-28 15:09:51 2013-02-28 15:10:11 Maintenance
24586  191     66th & Center   66th & Center 2013-02-28 15:10:09 2013-02-28 15:10:25 Maintenance
24587  191     66th & Center   66th & Center 2013-02-28 15:10:24 2013-02-28 15:10:47 Maintenance
24588  191     66th & Center   66th & Center 2013-02-28 15:10:49 2013-02-28 15:11:16 Maintenance

$`67th & Frances`
      Bike CheckoutKioskName ReturnKioskName  Checkout_date_time    Return_date_time    UserRole
24598  173    67th & Frances  67th & Frances 2013-02-28 16:39:27 2013-02-28 16:39:27 Maintenance
24599  230    67th & Frances  67th & Frances 2013-02-28 16:39:43 2013-02-28 16:39:43 Maintenance
24600  279    67th & Frances  67th & Frances 2013-02-28 16:40:22 2013-02-28 16:40:22  Subscriber
24616  102    67th & Frances  67th & Frances 2013-03-09 13:38:20 2013-03-09 18:41:42  Subscriber
24617   59    67th & Frances  67th & Frances 2013-03-09 13:39:09 2013-03-09 18:41:41  Subscriber
24619  279    67th & Frances  67th & Frances 2013-03-12 15:03:56 2013-03-12 15:04:53      Member

$`67th & Pine`
      Bike CheckoutKioskName ReturnKioskName  Checkout_date_time    Return_date_time    UserRole
24601  258       67th & Pine     67th & Pine 2013-02-28 16:57:08 2013-02-28 21:40:22 Maintenance
24602  258       67th & Pine  Aksarben Drive 2013-03-01 15:34:21 2013-03-01 20:36:37 Maintenance
24603  261       67th & Pine  Aksarben Drive 2013-03-01 15:34:25 2013-03-01 20:36:50 Maintenance
24622  279    67th & Frances     67th & Pine 2013-03-12 17:23:16 2013-03-12 17:27:03  Subscriber
24623   59    67th & Frances     67th & Pine 2013-03-12 17:23:29 2013-03-12 18:53:52      Member
24624  116    Aksarben Drive     67th & Pine 2013-03-12 17:38:05 2013-03-12 18:51:46      Member

我想要做的一个例子如下。我刚刚从列表中选取了一个元素来进行初始测试:

tes <- ex$`66th & Center`

c.tes <- tes[tes$CheckoutKioskName == '66th & Center',c('CheckoutKioskName','Checkout_date_time')]
c.tes$event <- rep(-1,length(c.tes))
names(c.tes) <- c('Station','Time','Event')
r.tes <- tes[tes$ReturnKioskName == '66th & Center', c('ReturnKioskName','Return_date_time')]
r.tes$event <- rep(1,length(r.tes))
names(r.tes) <- c('Station','Time','Event')
c.r.tes <- rbind(c.tes,r.tes)
c.r.tes <- c.r.tes[with(c.r.tes,order(Time)),]
c.r.tes$Tlapsed <- c(NA,c.r.tes[2:nrow(c.r.tes),c('Time')] - c.r.tes[-nrow(c.r.tes),c('Time')])

返回:

c.r.tes
         Station                Time Event Tlapsed
24583  66th & Center 2013-02-28 15:08:58    -1      NA
245831 66th & Center 2013-02-28 15:09:08     1      10
24584  66th & Center 2013-02-28 15:09:30    -1      22
24585  66th & Center 2013-02-28 15:09:51    -1      21
245841 66th & Center 2013-02-28 15:09:54     1       3
24586  66th & Center 2013-02-28 15:10:09    -1      15
245851 66th & Center 2013-02-28 15:10:11     1       2
24587  66th & Center 2013-02-28 15:10:24    -1      13
245861 66th & Center 2013-02-28 15:10:25     1       1
245871 66th & Center 2013-02-28 15:10:47     1      22
24588  66th & Center 2013-02-28 15:10:49    -1       2
245881 66th & Center 2013-02-28 15:11:16     1      27

我想要对列表的每个元素执行完全相同的过程。我希望我的最终输出类似于ex.events,其中包含150个元素,所有这些元素都具有与我的tes示例相同格式的data.frame。

我试图使用lapply来自己做这件事,我认为这是最有效的方法,但我似乎无法让错误停止。这是我尝试过的语法:

setNames(lapply(us, function(e){
c.e <- ex$e[ex$e$CheckoutKioskName == e ,c('CheckoutKioskName','Checkout_date_time')]
c.e$event <- rep(-1,length(c.e))
names(c.e) <- c('Station','Time','Event')
r.e <- ex$e[ex$e$ReturnKioskName == e , c('ReturnKioskName','Return_date_time')]
r.e$event <- rep(1,length(r.e))
names(r.e) <- c('Station','Time','Event')
c.r.e <- rbind(c.e,r.e)
c.r.e <- c.r.e[with(c.r.e,order(Time)),]
c.r.e$Tlapsed <- c(NA,c.r.e[2:nrow(c.r.e),c('Time')] - c.r.e[-nrow(c.r.e),c('Time')])
}),us)

我再次希望最终结果与我开始的列表的长度相同,但是每个元素都在其上完成了代码。

我一直在努力解决这个问题,所以我感谢任何帮助。

提前谢谢。

2 个答案:

答案 0 :(得分:1)

这不是一个完整的答案,因为完整的答案需要dput输入数据和us的描述。但是,它应该给你一些提示你的问题。我们假设您的数据是:

ex <- list(`66th & Center`=data.frame(CheckoutKioskName=c(1,2), ReturnKioskName=c(3,4)), `67th & Frances`=data.frame(CheckoutKioskName=c(5,6), ReturnKioskName=c(7,8)))

us是(请注意,不使用反引号):

us <- c("66th & Center","67th & Frances")

然后,

lapply(us, function(e) print(ex$e$CheckoutKioskName))
##NULL
##NULL
##[[1]]
##NULL
##
##[[2]]
##NULL

结果为NULL s。但是:

lapply(us, function(e) print(ex[[e]]$CheckoutKioskName))
##[1] 1 2
##[1] 5 6
##[[1]]
##[1] 1 2
##
##[[2]]
##[1] 5 6

给了我们想要的东西。

答案 1 :(得分:0)

考虑seq_along()函数中的lapply(),因为您需要提取单个元素的名称:

dfList <- lapply(seq_along(ex), function(i){ 
     # TEMP VARS
     item <- names(ex)[[i]]
     tempdf <- ex[[i]]  

     # CHECKOUT SUBSET
     c.e <- tempdf[tempdf$CheckoutKioskName == item, 
                   c('CheckoutKioskName','Checkout_date_time')] 
     c.e$event <- rep(-1, nrow(c.e))                           # OR c.e$event <- -1
     names(c.e) <- c('Station','Time','Event') 

     # RETURN SUBSET
     r.e <- tempdf[tempdf$ReturnKioskName == item, 
                   c('ReturnKioskName','Return_date_time')] 
     r.e$event <- rep(1, nrow(r.e))                            # OR r.e$event <- 1
     names(r.e) <- c('Station','Time','Event') 

     # COMBINED 
     df <- rbind(c.e, r.e) 
     df <- df[with(df,order(Time)),] 
     df$Tlapsed <- c(NA,df[2:nrow(df),c('Time')] - df[-nrow(df),c('Time')])
     return(df)    
})

dfList <- setNames(dfList, us)