需要帮助的地方不是太复杂,而是新的。 我有一个数据帧df,其中包含一列Product.id和一个价格Price。
Product.id price
A 11.5
A 11.5
A 12
A 13
A 13
B 9.25
B 9.75
B 9.75
B 9.5
我想使用自定义功能检查价格是否比上个月有所变化:
Check.Price.Change <- function(Vector){
for(x in 1:nrow(Vector)){
if(Vector[x] != Vector[x-1]){
TRUE
}
}
}
df <- df %>%
group_by(Product.id) %>%
mutate(if.Price.change = lapply(Price, Check.Price.Change))
我收到错误消息:
Error in 1:nrow(Vector) : argument of length 0
Called from: FUN(X[[i]], ...)
请问正确的方法是什么?
答案 0 :(得分:1)
我们可以使用lag
中的dplyr
与上一个条目进行比较。
library(dplyr)
df %>% group_by(Product.id) %>% mutate(is_changed = price != lag(price))
# Product.id price is_changed
# <fct> <dbl> <lgl>
#1 A 11.5 NA
#2 A 11.5 FALSE
#3 A 12 TRUE
#4 A 13 TRUE
#5 A 13 FALSE
#6 B 9.25 NA
#7 B 9.75 TRUE
#8 B 9.75 FALSE
#9 B 9.5 TRUE
类似地,shift
中有一个data.table
函数,其默认type
为"lag"
library(data.table)
setDT(df)[, is_changed := price != shift(price), by = Product.id]
数据
df <- structure(list(Product.id = structure(c(1L, 1L, 1L, 1L, 1L, 2L,
2L, 2L, 2L), .Label = c("A", "B"), class = "factor"), price = c(11.5,
11.5, 12, 13, 13, 9.25, 9.75, 9.75, 9.5)), class = "data.frame",
row.names = c(NA, -9L))
答案 1 :(得分:1)
如果上一个Price
与当前行的价格匹配,则下面的代码将添加一个指示符列。 lag
(和lead
)是dplyr函数,可让您有效地比较不同行中列的值。也是来自dplyr的向量化if_else
,如果满足条件,则将使值if.Price.change
TRUE
;如果不满足,则使值FALSE
;如果不能满足则将得到NA比较。请注意,由于无法从前一行提取值,因此无法对第一行进行比较。附带说明一下,lag
/ lead
让我们使用向前或向后比较多行,默认值为1。
使用dplyr:
df <- df %>% group_by(Product.id) %>%
mutate(if.Price.change = if_else(lag(Price) == Price, TRUE, FALSE, NA) %>% ungroup
# A tibble: 9 x 3
# Product.id Price if.Price.change
# <fct> <dbl> <lgl>
#1 A 11.5 NA
#2 A 11.5 TRUE
#3 A 12 FALSE
#4 A 13 FALSE
#5 A 13 TRUE
#6 B 9.25 NA
#7 B 9.75 FALSE
#8 B 9.75 TRUE
#9 B 9.5 FALSE