如何插入列并重复行直到 R 中的下一个变量
How to insert column and repeat rows until the next variable in R
例如,我有以下数据框 (df1
):
Date Price
2020-01-01 500
2020-01-02 550
2020-01-03 480
2020-01-04 420
2020-01-07 450
2020-01-08 390
2020-01-09 430
2020-01-11 480
2020-01-12 490
2020-01-13 485
我想在前一个数据框中插入 Price2
列,这样我就可以重复该行直到下一个日期,但是这个 "next date" 不在 df1
上数据框:
Date Price2
2020-01-05 50
2020-01-10 20
2020-01-13 90
会是这样的:
Date Price Price2
2020-01-01 500 50
2020-01-02 550 50
2020-01-03 480 50
2020-01-04 420 50
2020-01-07 450 20
2020-01-08 390 20
2020-01-09 430 20
2020-01-11 480 90
2020-01-12 490 90
2020-01-13 485 90
有人可以帮助我吗?
这是 tidyverse
方法 tidyr::fill
:
library(dplyr)
library(tidyr)
full_join(df1,df2) %>%
arrange(Date) %>%
tidyr::fill(Price2,.direction = "up") %>%
dplyr::filter(!is.na(Price))
Date Price Price2
1 2020-01-01 500 50
2 2020-01-02 550 50
3 2020-01-03 480 50
4 2020-01-04 420 50
5 2020-01-07 450 20
6 2020-01-08 390 20
7 2020-01-09 430 20
8 2020-01-11 480 90
9 2020-01-12 490 90
10 2020-01-13 485 90
假设带有 Price2
的第二个数据帧被称为 df2
:
library(magrittr)
lapply(df2$Date,function(x){
df2$Price2 * (df1$Date > x)
}) %>%
do.call(what = "+")
应该可以,如果不行请告诉我。
dplyr
+ zoo
:
library("dplyr")
library("zoo")
df = df1 %>%
full_join(df2, by = "Date") %>%
arrange(Date) %>%
mutate(Price2 = na.locf(Price2, fromLast = T)) %>%
filter(Date %in% df1$Date)
> df
Date Price Price2
1 2020-01-01 500 50
2 2020-01-02 550 50
3 2020-01-03 480 50
4 2020-01-04 420 50
5 2020-01-07 450 20
6 2020-01-08 390 20
7 2020-01-09 430 20
8 2020-01-11 480 90
9 2020-01-12 490 90
10 2020-01-13 485 90
这似乎有效:
library(data.table)
# Create Data
#df1 with all dates
df1 <- data.frame(Date = seq(as.Date("2020-01-01"),as.Date("2020-01-13"),by = "days"),
Price = c(500,550,480,420,450,390,430,480,490,485,485,490,450))
#drop dates included below:
df1<- df1[!df1$Date==c("2020-01-05","2020-01-08","2020-01-13"),]
# Set up df2
df2 <- data.frame(Date = as.Date(c("2020-01-05","2020-01-08","2020-01-13")),
Price2 = c(50,20,90))
setDT(df1)
setDT(df2)
setkey(df2, Date)[, dateMatch:=dateTarget]
df2[df1, roll='nearest']
虽然我的 Price2 和 Price 与您的预期输出相反,但我认为这在其他方面是一致的:
Date Price2 Price
1: 2020-01-01 50 500
2: 2020-01-02 50 550
3: 2020-01-03 50 480
4: 2020-01-04 50 420
5: 2020-01-05 50 450
6: 2020-01-06 50 390
7: 2020-01-07 20 430
8: 2020-01-09 20 490
9: 2020-01-10 20 485
10: 2020-01-11 90 485
11: 2020-01-12 90 490
12: 2020-01-13 90 450
使用 cut
.
res <-
transform(df1,
Price2=cut(1:nrow(df1),
c(0, rowSums(sapply(df1$Date, function(x)
df2$Date >= x))),
labels=df2$Price2))
res
# Date Price Price2
# 1 2020-01-01 500 50
# 2 2020-01-02 550 50
# 3 2020-01-03 480 50
# 4 2020-01-04 420 50
# 5 2020-01-07 450 20
# 6 2020-01-08 390 20
# 7 2020-01-09 430 20
# 8 2020-01-11 480 90
# 9 2020-01-12 490 90
# 10 2020-01-13 485 90
数据:
df1 <- read.table(text="Date Price
2020-01-01 500
2020-01-02 550
2020-01-03 480
2020-01-04 420
2020-01-07 450
2020-01-08 390
2020-01-09 430
2020-01-11 480
2020-01-12 490
2020-01-13 485", header=TRUE)
df1$Date <- as.Date(df1$Date)
df2 <- read.table(text="Date Price2
2020-01-05 50
2020-01-10 20
2020-01-13 90", header=TRUE)
df2$Date <- as.Date(df2$Date)
例如,我有以下数据框 (df1
):
Date Price
2020-01-01 500
2020-01-02 550
2020-01-03 480
2020-01-04 420
2020-01-07 450
2020-01-08 390
2020-01-09 430
2020-01-11 480
2020-01-12 490
2020-01-13 485
我想在前一个数据框中插入 Price2
列,这样我就可以重复该行直到下一个日期,但是这个 "next date" 不在 df1
上数据框:
Date Price2
2020-01-05 50
2020-01-10 20
2020-01-13 90
会是这样的:
Date Price Price2
2020-01-01 500 50
2020-01-02 550 50
2020-01-03 480 50
2020-01-04 420 50
2020-01-07 450 20
2020-01-08 390 20
2020-01-09 430 20
2020-01-11 480 90
2020-01-12 490 90
2020-01-13 485 90
有人可以帮助我吗?
这是 tidyverse
方法 tidyr::fill
:
library(dplyr)
library(tidyr)
full_join(df1,df2) %>%
arrange(Date) %>%
tidyr::fill(Price2,.direction = "up") %>%
dplyr::filter(!is.na(Price))
Date Price Price2
1 2020-01-01 500 50
2 2020-01-02 550 50
3 2020-01-03 480 50
4 2020-01-04 420 50
5 2020-01-07 450 20
6 2020-01-08 390 20
7 2020-01-09 430 20
8 2020-01-11 480 90
9 2020-01-12 490 90
10 2020-01-13 485 90
假设带有 Price2
的第二个数据帧被称为 df2
:
library(magrittr)
lapply(df2$Date,function(x){
df2$Price2 * (df1$Date > x)
}) %>%
do.call(what = "+")
应该可以,如果不行请告诉我。
dplyr
+ zoo
:
library("dplyr")
library("zoo")
df = df1 %>%
full_join(df2, by = "Date") %>%
arrange(Date) %>%
mutate(Price2 = na.locf(Price2, fromLast = T)) %>%
filter(Date %in% df1$Date)
> df
Date Price Price2
1 2020-01-01 500 50
2 2020-01-02 550 50
3 2020-01-03 480 50
4 2020-01-04 420 50
5 2020-01-07 450 20
6 2020-01-08 390 20
7 2020-01-09 430 20
8 2020-01-11 480 90
9 2020-01-12 490 90
10 2020-01-13 485 90
这似乎有效:
library(data.table)
# Create Data
#df1 with all dates
df1 <- data.frame(Date = seq(as.Date("2020-01-01"),as.Date("2020-01-13"),by = "days"),
Price = c(500,550,480,420,450,390,430,480,490,485,485,490,450))
#drop dates included below:
df1<- df1[!df1$Date==c("2020-01-05","2020-01-08","2020-01-13"),]
# Set up df2
df2 <- data.frame(Date = as.Date(c("2020-01-05","2020-01-08","2020-01-13")),
Price2 = c(50,20,90))
setDT(df1)
setDT(df2)
setkey(df2, Date)[, dateMatch:=dateTarget]
df2[df1, roll='nearest']
虽然我的 Price2 和 Price 与您的预期输出相反,但我认为这在其他方面是一致的:
Date Price2 Price
1: 2020-01-01 50 500
2: 2020-01-02 50 550
3: 2020-01-03 50 480
4: 2020-01-04 50 420
5: 2020-01-05 50 450
6: 2020-01-06 50 390
7: 2020-01-07 20 430
8: 2020-01-09 20 490
9: 2020-01-10 20 485
10: 2020-01-11 90 485
11: 2020-01-12 90 490
12: 2020-01-13 90 450
使用 cut
.
res <-
transform(df1,
Price2=cut(1:nrow(df1),
c(0, rowSums(sapply(df1$Date, function(x)
df2$Date >= x))),
labels=df2$Price2))
res
# Date Price Price2
# 1 2020-01-01 500 50
# 2 2020-01-02 550 50
# 3 2020-01-03 480 50
# 4 2020-01-04 420 50
# 5 2020-01-07 450 20
# 6 2020-01-08 390 20
# 7 2020-01-09 430 20
# 8 2020-01-11 480 90
# 9 2020-01-12 490 90
# 10 2020-01-13 485 90
数据:
df1 <- read.table(text="Date Price
2020-01-01 500
2020-01-02 550
2020-01-03 480
2020-01-04 420
2020-01-07 450
2020-01-08 390
2020-01-09 430
2020-01-11 480
2020-01-12 490
2020-01-13 485", header=TRUE)
df1$Date <- as.Date(df1$Date)
df2 <- read.table(text="Date Price2
2020-01-05 50
2020-01-10 20
2020-01-13 90", header=TRUE)
df2$Date <- as.Date(df2$Date)