【问题标题】:Lapply within a lappy in R在 R 中的 lappy 中应用
【发布时间】:2020-10-16 15:52:30
【问题描述】:

LApply-ception? 无论如何。

我有一个数据框列表。我通过它并进行调整就好了。但是我需要应用每个单独的数据帧,即遍历列表中的每个数据帧。

所以下面的作品。

#THIS WORKS
bottleneck_fury <- function(bottleneck2) {
  
  bottleneck2 <- bottleneck2 %>% 
    mutate(startTime = as_datetime(startTime, tz = "")) %>% 
    mutate(endTime = as_datetime(endTime, tz = "")) %>% 
    mutate(early_startTime = startTime - 300) %>% #5 min prior
    mutate_at(c("startTime", "endTime", "early_startTime"),anytime) %>%  #formatted time
    mutate(id = rownames(bottleneck2)) 
  
  bottleneck2 
}

all_necks <- lapply(bottleneck_test, bottleneck_fury)
dd <- all_necks[[1]]


OUTPUT
dd <- structure(list(startTime = structure(c(1533122400, 1533132060, 
1533151920, 1533205740, 1533207960), class = c("POSIXct", "POSIXt"
), tzone = ""), endTime = structure(c(1533131340, 1533132540, 
1533153300, 1533207660, 1533218460), class = c("POSIXct", "POSIXt"
), tzone = ""), impact = c(627.06, 26.53, 24.34, 166.84, 761.39
), impactPercent = c(1444.6, 33.98, 30.98, 320.75, 1632.12), 
    impactSpeedDiff = c(25814.55, 806.43, 733.5, 6289.26, 30350.4
    ), maxQueueLength = c(4.829494, 3.605648, 2.241074, 5.760513, 
    5.760513), tmcs = list(c("110N04623", "110-04623", "110N04624", 
    "110-04624", "110N04625", "110-04625", "110N04626", "110-04626"
    ), c("110N04623", "110-04623", "110N04624", "110-04624", 
    "110N04625", "110-04625"), c("110N04623", "110-04623", "110N04624", 
    "110-04624"), c("110N04623", "110-04623", "110N04624", "110-04624", 
    "110N04625", "110-04625", "110N04626", "110-04626", "110N04627"
    ), c("110N04623", "110-04623", "110N04624", "110-04624", 
    "110N04625", "110-04625", "110N04626", "110-04626", "110N04627"
    )), early_startTime = structure(c(1533122100, 1533131760, 
    1533151620, 1533205440, 1533207660), class = c("POSIXct", 
    "POSIXt"), tzone = ""), id = c("1", "2", "3", "4", "5")), row.names = c(NA, 
5L), class = "data.frame")

现在我拉出这个数据框并对其进行操作,我想在它上面运行一个循环。但是,当我需要它作为数据框时,结果是一个列表。此处的第二个 lapply 现在已更改为代表实际情况以及 unlist() 不起作用的原因。

#DOESNT WORK
bottleneck_fury <- function(bottleneck2) {
  
 # bottleneck2 <- data.frame(matrix(unlist(bottleneck), nrow=length(bottleneck), byrow=T))
  
  bottleneck2 <- bottleneck2 %>% 
    mutate(startTime = as_datetime(startTime, tz = "")) %>% 
    mutate(endTime = as_datetime(endTime, tz = "")) %>% 
    mutate(early_startTime = startTime - 300) %>% #5 min prior
    mutate_at(c("startTime", "endTime", "early_startTime"),anytime) %>%  #formatted time
    mutate(id = rownames(bottleneck2)) 
  
  bottleneck2 
  #md_events2 <-  md_events 
  
  
  test <- lapply(1:nrow(bottleneck2), function(x) {
    #go row by row
    bottleneck_row <- bottleneck2[x,]
    events <- iris[which(bottleneck_row$maxQueueLength < iris$Petal.Length ==TRUE),]

    ID <- do.call("rbind",replicate(nrow(events), bottleneck_row, simplify = FALSE))
    cbind(events, ID)
}

}

all_necks <- lapply(bottleneck_test, bottleneck_fury)
dd <- all_necks[[1]]
View(dd)

我希望 R 可以在 lapply 中执行 lapply 并为列表中的两个数据框提供一个新的数据框。

最后,dd 应该是一个数据帧,它是列表all_necks 中的第一个数据帧。

【问题讨论】:

  • 1) 你有两个同名的函数,问题出在第二个吗? 2)运行第一个函数后数据集是dd
  • 问题是 #2,是的,这是工作函数之后的 dd
  • 你能分享你的原始数据bottleneck_test 并显示预期的输出吗?
  • 即使一个子集太大,但很高兴在聊天室中通过私人消息这样做

标签: r list dplyr apply lapply


【解决方案1】:

虽然您使用的数据框不大,但最好将数据框整合为一个,并用 id 进行标识。这使得该过程更加高效。您可以使用“plyr”包的“ldply”功能来完成此操作,该功能可以将文件集成到特定文件夹中,您可以根据文件名称后的模式选择该文件夹。您可以对每个文件应用一个函数来执行此操作。在您的情况下,您可以通过以下方式进行:

library(plyr)
setwd("~/directory")
all_necks<- ldply(.data = list.files(pattern = "some-pattern"),   .fun = function(x){
              y<-read.csv(x,header=T) 
              y$ID <- x 
              y
              } ### The function read the file and creates a new column that stores a unique ID for each file.
) 

第二部分我了解您尝试识别数据框“iris”的观察结果,这些观察结果对于数据框“events”中变量“maxQueueLength”的每个值都更大。然后你复制 nrow (events) 次对 data.framebottleneck2 的每个观察,并将其存储在变量 ID 中;我不太明白这样做的目的是什么。但是您可以在不使用 for 循环的情况下以更有效的方式执行此操作(最好避免使用它们并尽可能多地使用它们并且 lapply 或 sapply,因为它们不再比这些更有效,显然这并不总是可能)。

避免使用它们的一个策略是将您的数据框“全部”扩展到您使用的 for 循环将生成的行数,这将是 nrow (iris) 的乘积,满足您指定的条件,乘以 nrow (all_necks)。虽然,为了防止您多次检查变量“maxQueueLength”的值是否符合您的条件,而不是具有 nrow (all_necks) 它将具有长度(唯一 (all_necks$maxQueueLength)),在代码中这是使用与 dplyr 不同的功能完成。在执行此操作之前,您在“all_necks”中添加带有 NA 的变量“Sepal.Length”,使其具有与“all_necks”相同的长度()。 集成数据框后,使用 group_by () 函数按变量“maxQueueLength”进行分组。每个组都有数据帧“iris”的长度(),这是为了在“Petal.Length”的每个值与“maxQueueLength”的每个值之间进行比较。最后,您使用 mutate() 来检查每个值组合的条件,就是这样。结果应该是 data.frame 并且它应该花费更少的时间来执行。

library(dplyr)

nrow_iris <- nrow(iris)
nrow_necks<- nrow(all_necks)

all_necks<- all_necks %>% add_column(Sepal_length = c(iris$Sepal.Length,rep(NA,nrow_necks-nrow_iris)) )
all_necks_2 <- all_necks %>% distinct(maxQueueLength,.keep_all = T)
all_necks_2 <- do.call("rbind",replicate(nrow_iris*length(all_necks_2$maxQueueLength),all_necks,simplify = F ))

all_necks_2<- all_necks_2 %>% group_by(maxQueueLength) %>% mutate(new=maxQueueLength < Petal.Length) %>% ungroup()
all_necks_2 %>% count(vars = new)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-16
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多