Использование lapply для выполнения нескольких операций над многими элементами списка в R

r list dataframe element lapply

133 просмотра

2 ответа

В настоящее время у меня есть список из 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 элементов, каждый из которых имел бы data.frame в том же формате, что и мой tesпример.

Я пытался сделать это сам, используя, по 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)

Я снова хочу, чтобы конечный результат был такой же длины списка, с которого я начинал, но с каждым элементом, на котором был сделан код.

Я действительно боролся с этим, поэтому я ценю любую помощь, которую я могу получить.

Заранее спасибо.

Автор: Brett Источник Размещён: 08.11.2019 11:23

Ответы (2)


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с. Тем не мение:

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

дает нам то, что мы хотим.

Автор: aichao Размещён: 20.08.2016 03:05

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)
Автор: Parfait Размещён: 20.08.2016 05:09
Вопросы из категории :
32x32