如果最后一个obs小于特定值,如何删除一组数据?

时间:2018-09-12 13:44:41

标签: r dplyr

我正在处理一些库存数据,但是在清理数据的某些方面遇到了问题。

由于我掌握了美国大部分最大股票的数据,因此我想摆脱所有股票,如果

  1. 最后一天的股票价格低于25美元(仅由#组成)

我该如何进行编码,最好不必使用for循环?

例如-假设我有以下数据集:

Date       ID    EOD_Price  
2/1/10    AAPL    45.1
2/2/10    AAPL    45.3
2/3/10    AAPL    45.1   
 ...      ...     ...
2/1/10    JXL      2.6
2/2/10    JXL      2.5
2/3/10    JXL      2.8
 ...      ...      ...
2/1/10    RXW      26.5
2/2/10    RXW      25.9
2/3/10    RXW      24.9

...本质上,由于最后一个日期(2/3/10)的价格> 25,因此我的结果将只包括AAPL的所有数据。

关于如何执行此操作的任何想法?

下面的代码是我认为将为每只股票生成最后一个obs的东西,然后我可以在for循环中使用它来子集化(可能不太确定):

data %>% group_by(ID) %>% tail(EOD_Price, n=1) 

但这只会产生数据集中最后一个obs的最后一个值。

请告知。我只想保留最后一天价格> 25美元的ID。

非常感谢!继续学习!

3 个答案:

答案 0 :(得分:3)

使用dplyr::last只能选择最后一个值大于25的股票“ ID”

library(dplyr) 
df %>% group_by(ID) %>% filter(last(value)>25)

# A tibble: 3 x 3
# Groups:   ID [1]
  date   ID value
  <chr>  <chr> <dbl>
1 2/1/10 AAPL   45.1
2 2/2/10 AAPL   45.3
3 2/3/10 AAPL   45.1

#Another option is using n() instead of last, 
#where n() is number of rows (observatrions) in that group
df %>% group_by(stock) %>% filter(value[n()]>25) 

数据

structure(list(date = c("2/1/10", "2/2/10", "2/3/10", "2/1/10", 
 "2/2/10", "2/3/10", "2/1/10", "2/2/10", "2/3/10"), ID = c("AAPL", 
 "AAPL", "AAPL", "JXL", "JXL", "JXL", "RXW", "RXW", "RXW"), value = c(45.1, 
 45.3, 45.1, 2.6, 2.5, 2.8, 26.5, 25.9, 24.9)), class = "data.frame", row.names = c(NA,-9L))

答案 1 :(得分:1)

使用sqldf

# Inner query: group by ID and check if EOD_Price>25 and 
#Outer query: select all rows which are belongs to the inner ID
library(sqldf)
sqldf("select * from df where ID in (select ID from df group by ID having EOD_Price>25)")

输出:

    Date   ID EOD_Price
1 2/1/10 AAPL      45.1
2 2/2/10 AAPL      45.3
3 2/3/10 AAPL      45.1

答案 2 :(得分:1)

带有data.table

的选项
library(data.table)
setDT(df1)[, .SD[last(value) > 25], by = ID]
#      ID   date value
#1: AAPL 2/1/10  45.1
#2: AAPL 2/2/10  45.3
#3: AAPL 2/3/10  45.1

数据

df1 <- structure(list(date = c("2/1/10", "2/2/10", "2/3/10", "2/1/10", 
"2/2/10", "2/3/10", "2/1/10", "2/2/10", "2/3/10"), ID = c("AAPL", 
"AAPL", "AAPL", "JXL", "JXL", "JXL", "RXW", "RXW", "RXW"), value = c(45.1, 
45.3, 45.1, 2.6, 2.5, 2.8, 26.5, 25.9, 24.9)), class = "data.frame", 
 row.names = c(NA, -9L))