簡體   English   中英

使用lapply進行矢量化,而不是使用For循環

[英]Vectorizing with lapply instead of using For loop

我試圖擺脫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

在此處輸入圖片說明

我在這里(lapply)這里(lapply)這里($運算符)找到了相關問題,但沒有一個問題真正對我有幫助。

這是我嘗試使用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

我的真實數據集有數十萬行。 如果有人可以向我指出如何向量化的正確方向,以獲得與For循環相同的輸出,我將不勝感激。

謝謝!

所以lapply在這里並沒有被完全使用,僅此lapply

lapply將函數應用於列表的每個元素。 明確地說,它接受列表的每個元素,並將函數應用於該元素。

因此,如果希望它將功能應用於數據框的多個子集,則需要為其獲取一個列表,該列表是數據框的多個子集。 因此,讓我們首先創建該列表。

我們可以使用split函數來做到這一點,它將基於一列的數據幀分為幾個數據幀,並將它們存儲為列表。 數據幀的子集列表。 完善!

因此,讓我們用該行替換您創建mylist行。

mylist <- split(df,df[,c("Item")])

現在,我們只需要進行一些修改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)
}

其余的我朋友,就和您擁有的一樣:)

我不知道lapply是采取正確的方法。 我堅持使用mutate您似乎已經在使用它:

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
df <- data.frame(Date  = rep(c("Jan1", "Jan2", "Jan3"), 3),
  Item  = c(rep("A", 3), rep("B", 3), rep("C", 3)),
  Value = 10:18)

df <- df %>%
  group_by(Item) %>%
  mutate(diff = last(Value) - Value)

df
#> # A tibble: 9 x 4
#> # Groups:   Item [3]
#>   Date  Item  Value  diff
#>   <fct> <fct> <int> <int>
#> 1 Jan1  A        10     2
#> 2 Jan2  A        11     1
#> 3 Jan3  A        12     0
#> 4 Jan1  B        13     2
#> 5 Jan2  B        14     1
#> 6 Jan3  B        15     0
#> 7 Jan1  C        16     2
#> 8 Jan2  C        17     1
#> 9 Jan3  C        18     0

reprex軟件包 (v0.2.0)於2018-06-27創建。

這確實假定觀察結果(至少在“項目”組中)是按順序排列的。 如果不是,請在group_by之后添加arrange(Date) %>%

您可以創建一個具有最新值的表,與原始表連接並獲得差異或使用data.table創建一個具有最新值的附加列

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

setDT(df)

df[,latestVal:=last(Value),by=.(Item)][,diff:=latestVal-Value][,.(Date,Item,Value,diff)]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM