我有一个大约3000行的数据框。我希望找到最长的正数和负数。
我的示例数据框:df
1 0.502310591
2 -0.247577976
3 -0.307256769 2
4 0.442253678
5 -0.795770351
6 2.08244648
7 -0.01672777
8 -0.164145656 2
9 0.610117365
10 0.014758371
11 0.381105476
12 0.721386493 4
13 -0.363222383
14 0.201409322
15 0.724867214
16 -1.586829584
17 1.066288451
18 0.182824494
19 0.237447191
20 -0.215475797
最长的正面运行:4 最长的负面运行:2
我正在关注本教程:https://ocw.mit.edu/ans7870/18/18.05/s14/html/r-tut-rle.html
我需要资助最长的值&gt; 0并且还<0。那么有什么方法可以编辑上面的内容吗?
我猜这只发现最长的1,0?如果是那种情况,那么我需要一个辅助列ifelse 1,0来分割负数,正数...然后可能找到最长的代码:
> df$wins <- ifelse(df$V2 > 0, 1, 0)
> df$loss <- ifelse(df$V2 < 0, 1, 0)
> win <- (c(df$wins))
> max(rle(win)$lengths)
[1] 4
这适用于寻找最大胜利......
这是为了损失:
> print(df$loss)
[1] 0 1 1 0 1 0 1 1 0 0 0 0 1 0 0 1 0 0 0 1
> df$loss <- ifelse(df$V2 < 0, 1, 0)
> print(df$loss)
[1] 0 1 1 0 1 0 1 1 0 0 0 0 1 0 0 1 0 0 0 1
> loss <- (c(df$loss))
> max(rle(loss)$lengths)
[1] 4
不确定为什么它说4 ...显然有2个最大损失,有谁知道为什么? 我错过了什么,胜利的逻辑不应该对损失完全相同吗?我看不到代码中的任何错误......
如果df $ loss中的值小于0则打印1否则为0。
制作一个包含df $ loss列内容的向量
使用max(rle(loss)$lengths)
找到1的最大长度
再次结果是4 ..然而,它显然是2?
答案 0 :(得分:1)
我认为rle
将根据您的目标完成工作,但我会发布一个替代解决方案,稍微更多的数据操作,但您将能够获得更多信息。
通常,在回答一个问题后,您将被要求回答更多问题。例如,了解正数与负数的运行分布,因为最大值可能不会告诉您太多。或者,进行统计比较,看看阳性是否比平均阴性更长。
此外,在大约3000行的情况下,我认为你没有任何速度问题。
library(dplyr)
# example dataset
dt = data.frame(x = c(1,-1,-2,0,2,4,3,5,-5,-6,-7,0,0))
# get a dataset that assigns an id to all positive or negative series
dt %>%
mutate(sign = ifelse(x > 0, "pos", ifelse(x < 0, "neg", "zero")), # get the sign of the value
sign_lag = lag(sign, default = sign[1]), # get previous value (exception in the first place)
change = ifelse(sign != sign_lag, 1 , 0), # check if there's a change
series_id = cumsum(change)+1) %>% # create the series id
print() -> dt2 # print to screen and save it
# x sign sign_lag change series_id
# 1 1 pos pos 0 1
# 2 -1 neg pos 1 2
# 3 -2 neg neg 0 2
# 4 0 zero neg 1 3
# 5 2 pos zero 1 4
# 6 4 pos pos 0 4
# 7 3 pos pos 0 4
# 8 5 pos pos 0 4
# 9 -5 neg pos 1 5
# 10 -6 neg neg 0 5
# 11 -7 neg neg 0 5
# 12 0 zero neg 1 6
# 13 0 zero zero 0 6
您可以删除帮助列sign_lag
和change
,因为我已将它们包含在内,仅用于说明该过程的工作原理。
# Get longest runs
dt2 %>%
count(sign, series_id) %>%
group_by(sign) %>%
filter(n == max(n)) %>%
select(-series_id) %>%
ungroup
# # A tibble: 3 x 2
# sign n
# <chr> <int>
# 1 neg 3
# 2 pos 4
# 3 zero 2
# Get all runs
dt2 %>% count(sign, series_id)
# # A tibble: 6 x 3
# sign series_id n
# <chr> <dbl> <int>
# 1 neg 2 2
# 2 neg 5 3
# 3 pos 1 1
# 4 pos 4 4
# 5 zero 3 1
# 6 zero 6 2
如果你得到所有跑步,你将能够绘制积极与阴性的分布,或进行统计比较,看看阳性平均值是否比阴性更长。
答案 1 :(得分:1)
这是一种简单的方法,我假设你开始只使用一个数据框,我也假设你需要一个数据帧,其中相同数字的计数运行一列为正数,一列为负数
set.seed(42)
df=data.frame(x= runif(300, -1.0, 1.0))
count_pos=c()
count_neg=c()
n1=df$x[1]
if (sign(n1)==1){
count_pos[1]=1
count_neg[1]=0
}else{
count_neg[1]=1
count_pos[1]=0
}
count=1
index=1
for (i in df$x[2:nrow(df)]){
#print (i)
index=index+1
if (sign(n1)==sign(i)){
count=count+1
}
else{
count=1
}
if (sign(i)==1){
count_pos[index]=count
count_neg[index]=0
}else{
count_pos[index]=0
count_neg[index]=count
}
n1=i
}
df2=data.frame(x=df$x,count_pos=count_pos,count_neg=count_neg)
#df2 contains the dataframe with columns that count the run for numbers with
#same sign
print (paste("Maximum run of Positive numbers:",max(count_pos)))
print (paste("Maximun run of negative numbers:",max(count_neg)))
我知道有一种更紧凑的方法可以做到这一点,但这段代码可以解决问题。
答案 2 :(得分:1)
要获得系列中的最大正/负运行(在您的情况下,在data.frame的列中,rle
函数就是您所需要的:
set.seed(123)
df <- data.frame(col1=rnorm(20, mean = 0, sd = 1))
最大。 pos run:
max(rle(sign(df$col1))[[1]][rle(sign(df$col1))[[2]] == 1])
[1] 5
最大。 neg.run:
max(rle(sign(df$col1))[[1]][rle(sign(df$col1))[[2]] == -1])
[1] 3
让我们检查一下结果:
> df
col1
1 -0.56047565
2 -0.23017749
3 1.55870831
4 0.07050839
5 0.12928774
6 1.71506499
7 0.46091621
8 -1.26506123
9 -0.68685285
10 -0.44566197
11 1.22408180
12 0.35981383
13 0.40077145
14 0.11068272
15 -0.55584113
16 1.78691314
17 0.49785048
18 -1.96661716
19 0.70135590
20 -0.47279141