使用lapply而不是使用For循环进行矢量化

Dav*_*veM 0 for-loop r vectorization lapply

我试图摆脱R中的循环,并期待矢量化和加速我的代码的一部分.

我希望使用lapply转换For循环,但是收到错误: 在此输入图像描述

可重复的例子:

library(dplyr)

# This works using a For loop -----------------------------------

# create sample data frame
df <- data.frame(Date  = rep(c("Jan1", "Jan2", "Jan3"), 3),
                 Item  = c(rep("A", 3), rep("B", 3), rep("C", 3)),
                 Value = 10:18)


diff <- numeric() # initialize

# Loop through each item and take difference of latest value from earlier values
for (myitem in unique(df$Item)) {

    y = df[df$Date == last(df$Date) & df$Item == myitem, "Value"]  # Latest value for an item

    x = df[df$Item == myitem, "Value"]                             # Every value for an item

    diff <- c(diff, y-x)

}

df_final <- mutate(df, Difference = diff)
df_final
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我在这里(lapply),这里(lapply)这里($ operator)找到了相关的问题,但没有一个真正帮助我解决了我的问题.

以下是我尝试使用lapply进行矢量化的方法:

# Same thing using vectorized approach ----------------------------------

mylist <- list(unique(df$Item))

myfunction <- function(df = df, diff = numeric()) {

    y = df[df$Date == last(df$Date) & df$Item == mylist, "Value"]  # Latest value for an item

    x = df[df$Item == mylist, "Value"]                             # Every value for an item

    diff <- c(diff, y-x)

}

# throws error
diff_vector <- unlist(lapply(mylist, myfunction))

df_final2 <- mutate(df, Difference = diff_vector)
df_final2
Run Code Online (Sandbox Code Playgroud)

我的真实数据集有数十万行.如果有人可以指出我正确的方向如何向量化它以获得与For循环相同的输出我会很感激.

谢谢!

Lac*_*anO 5

所以lapply这里没有被使用,这就是全部!

lapply将函数应用于列表的每个元素.为了明确,它接受列表的每个元素,并将该函数应用于该元素.

因此,如果您希望将函数应用于数据框的多个子集,则需要获取一个列表,该列表是数据框的多个子集.所以让我们先创建该列表.

我们可以使用split函数执行此操作,它会根据列将数据框拆分为多个数据框,并将它们存储为列表.数据框的子集列表.完善!

因此,让我们mylist用这一行替换你创建的行.

mylist <- split(df,df[,c("Item")])
Run Code Online (Sandbox Code Playgroud)

现在我们只需要进行一些更改myfunction.请记住,我们现在已经将我们的数据传递给了子集,因此我们可以删除Item与我们期望的匹配条件.请记住,此功能将完全应用于每个数据框.

myfunction <- function(df = df, diff = numeric()) { 
    y = df[df$Date == last(df$Date), "Value"]  # Latest value for an item

    x = df[, "Value"]                             # Every value for an item

    diff <- c(diff, y-x)
}
Run Code Online (Sandbox Code Playgroud)

其余的我的朋友,就像你拥有它:)