我试图摆脱R中的循环,并希望矢量化和加速我的代码的一部分。
可复制的示例:
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
我发现了相关的问题here (lapply),here (lapply)和here ($ 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
我的真实数据集有数十万行。如果有人可以向我指出正确的方向,如何进行矢量化以获得与For循环相同的输出,我将不胜感激。
谢谢!
答案 0 :(得分:5)
所以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)
}
剩下的我的朋友,正是您所拥有的:)
答案 1 :(得分:1)
我不确定JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].click();","Target Webelement");
是采用的正确方法。我坚持使用lapply
-您似乎已经在使用它:
mutate
由reprex package(v0.2.0)于2018-06-27创建。
这确实假定观察结果(至少在“项目”组中)是按顺序排列的。如果不是,请在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
arrange(Date) %>%
答案 2 :(得分:1)
您可以创建一个具有最新值的表,与原始表连接并获得差异,或使用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)]