在数据框内。我想将今天的价值与回顾'n'天期间的价值进行比较。
我知道如何在excel中比较今天的价值,看它是否高于前10天。
=IF(A11>MAX(A1:A10),1,0)
如何在R中的函数中执行相同的逻辑?
输出如下所示:
Column Output
1 12 NA
2 13 NA
3 14 NA
4 15 NA
5 9 NA
6 9 NA
7 7 NA
8 8 NA
9 16 NA
10 17 NA
11 20 1
12 14 0
13 9 0
14 8 0
15 6 0
16 5 0
17 28 1
在第11行中。因为值20高于前10天,所以它表示1值。
在第12行中,因为值14不是前10天中的最高数字,所以它获得0值。
它当然会在移动10天的窗口上滚动。
答案 0 :(得分:4)
P Lapointe的回答非常好,但无论何时我都在做一个“滚动”的回答。计算我的第一直觉是从动物园包中想到rollapply
。
is_last_greatest <- function(x){
#' Given an input vector this returns
#' 1 if the last element is greater than
#' all of the other elements and 0 otherwise
ifelse(all(tail(x,1) > head(x,-1)), 1, 0)
}
# We want to compare to the previous 10 values but the function
# I wrote requires us to include the value we're using as
# comparison so I set the width to 11
output <- rollapply(dat,
width = 11,
FUN = is_last_greatest,
fill = NA,
align = "right")
cbind(dat, output)
给出了
dat vals
[1,] 12 NA
[2,] 13 NA
[3,] 14 NA
[4,] 15 NA
[5,] 9 NA
[6,] 9 NA
[7,] 7 NA
[8,] 8 NA
[9,] 16 NA
[10,] 17 NA
[11,] 20 1
[12,] 14 0
[13,] 9 0
[14,] 8 0
[15,] 6 0
[16,] 5 0
[17,] 28 1
答案 1 :(得分:3)
以下是roll_maxr
中RcppRoll
的使用方法。
library(RcppRoll)
df$Output2 <- ifelse(df$Column>roll_maxr(lag(df$Column),11, na.rm = TRUE),1,0)
Column Output Output2
1 12 NA NA
2 13 NA NA
3 14 NA NA
4 15 NA NA
5 9 NA NA
6 9 NA NA
7 7 NA NA
8 8 NA NA
9 16 NA NA
10 17 NA NA
11 20 1 1
12 14 0 0
13 9 0 0
14 8 0 0
15 6 0 0
16 5 0 0
17 28 1 1
数据强>
df <- read.table(text=" Column Output
1 12 NA
2 13 NA
3 14 NA
4 15 NA
5 9 NA
6 9 NA
7 7 NA
8 8 NA
9 16 NA
10 17 NA
11 20 1
12 14 0
13 9 0
14 8 0
15 6 0
16 5 0
17 28 1",header=TRUE,stringsAsFactors=FALSE)
答案 2 :(得分:1)
以下是使用embed
构建比较集并与apply
进行比较的基本R方法。
# get a matrix for comparisons
myMat <- embed(df$Column, 11)
此处返回
myMat
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
[1,] 20 17 16 8 7 9 9 15 14 13 12
[2,] 14 20 17 16 8 7 9 9 15 14 13
[3,] 9 14 20 17 16 8 7 9 9 15 14
[4,] 8 9 14 20 17 16 8 7 9 9 15
[5,] 6 8 9 14 20 17 16 8 7 9 9
[6,] 5 6 8 9 14 20 17 16 8 7 9
[7,] 28 5 6 8 9 14 20 17 16 8 7
因此,我们的目标是将第一列中的值与每行中剩余列中的值进行比较。
as.integer(max.col(myMat) == 1L)
[1] 1 0 0 0 0 0 1
现在,确定适当数量的NA值,即myMat中的列数减1。
df$output2 <- c(rep(NA, ncol(myMat) - 1), as.integer(max.col(myMat) == 1L))
返回
df
Column Output output2
1 12 NA NA
2 13 NA NA
3 14 NA NA
4 15 NA NA
5 9 NA NA
6 9 NA NA
7 7 NA NA
8 8 NA NA
9 16 NA NA
10 17 NA NA
11 20 1 1
12 14 0 0
13 9 0 0
14 8 0 0
15 6 0 0
16 5 0 0
17 28 1 1
max.col
的一个优点是速度非常快。它最大的缺点之一是它没有na.rm参数来删除缺失值。如果缺少值,则可以使用myMat而不是apply
上的max.col
方法。
apply(myMat, 1, function(x) as.integer(all(head(x, 1) > tail(x, -1))))
这里的操作比较功能是
all(head(x, 1) > tail(x, -1))
产生相同结果的函数包括以下
head(x, 1) == max(x) # or
x[1] == max(x)
和
1L == which.max(x)