动态更新/组合R中的两个data.Frame

动态更新/组合R中的两个data.Frame,r,vector,merge,dataframe,R,Vector,Merge,Dataframe,我还没有在网上找到一个解决方案,因为要提出正确的问题并不容易。 我有两个data.frames,x和y,希望将它们组合起来得到z: 棘手的是z比较x和y的日期值,并采用最新的观测值来更新A、B、C和D。因此“动态”更新/合并 x=data.frame(c("2000-01-01","2000-06-01","2001-01-01"),c("100","100","100"),c("200","200","200")) colnames(x)=c("Date","A","B") y=data.f

我还没有在网上找到一个解决方案,因为要提出正确的问题并不容易。 我有两个data.frames,x和y,希望将它们组合起来得到z:

棘手的是z比较x和y的日期值,并采用最新的观测值来更新A、B、C和D。因此“动态”更新/合并

x=data.frame(c("2000-01-01","2000-06-01","2001-01-01"),c("100","100","100"),c("200","200","200"))
colnames(x)=c("Date","A","B")

y=data.frame(c("2000-01-05","2000-04-09"),c("10","0"),c("0","35"))
colnames(y)=c("Date","C","D")

z=data.frame(c("2000-01-01","2000-01-05","2000-04-09","2000-06-01","2001-01-01"),c("100","100","100","100","100"),c("200","200","200","200","200"),c("0","10","10","0","0"),c("0","0","35","0","0"))
colnames(z)=c("Date","A","B","C","D")

x$Date = as.Date(x$Date)
y$Date = as.Date(y$Date)
问题:如何通过有效的代码到达
z

举例说明:

> x
        Date   A   B
1 2000-01-01 100 200
2 2000-06-01 100 200
3 2001-01-01 100 200
> y
        Date  C  D
1 2000-01-05 10  0
2 2000-04-09  0 35
> z
        Date   A   B  C  D
1 2000-01-01 100 200  0  0
2 2000-01-05 100 200 10  0
3 2000-04-09 100 200 10 35
4 2000-06-01 100 200 10 35
5 2001-01-01 100 200 10 35
> 
编辑: 谢谢你的回答。 解决方案似乎是一个简单的完全连接,然后是一个循环中的一个循环(我想出了第二步):

编辑2:下面其他人发布的解决方案似乎更有效。为了完整起见,如果y中的0被NA替换,则我的较长解决方案有效,即将y定义为:

y=data.frame(c("2000-01-05","2000-04-09"),c("10",NA),c(NA,"35"))
colnames(y)=c("Date","C","D")
然后在最后一步中更换z中的NAs

我从我的第一次编辑中了解到,为了避免混淆,我没有编辑上面的原始问题


非常感谢你的帮助

一种可能的解决方案是结合使用
data.table
zoo
包装中的
na.locf
功能:

# loading the needed packages
library(data.table)
library(zoo)

# converting x & y to datatables
setDT(x)
setDT(y)

# merge x & y into z
z <- merge(x, y, by="Date", all=TRUE) # this works in base R as well

# fill the NA's with the last observation
cols <- c("A","B","C","D") # in this specific case, you can also use: LETTERS[1:4]
z[, (cols) := lapply(.SD, na.locf, rule = 1, na.rm=FALSE), .SDcols= cols]
正如@Tensibai在评论中提到的那样,这个结果也可以在base R中实现(由于某种原因,最初在我的系统上不起作用):

在base R中,您将执行以下操作:

z <- merge(x, y, by="Date", all=TRUE)
z[z==0] <- NA
z <- na.locf(z)
z[is.na(z)] <- 0

z一种可能的解决方案是结合使用
data.table
na.locf
功能,该功能来自
zoo
包装:

# loading the needed packages
library(data.table)
library(zoo)

# converting x & y to datatables
setDT(x)
setDT(y)

# merge x & y into z
z <- merge(x, y, by="Date", all=TRUE) # this works in base R as well

# fill the NA's with the last observation
cols <- c("A","B","C","D") # in this specific case, you can also use: LETTERS[1:4]
z[, (cols) := lapply(.SD, na.locf, rule = 1, na.rm=FALSE), .SDcols= cols]
正如@Tensibai在评论中提到的那样,这个结果也可以在base R中实现(由于某种原因,最初在我的系统上不起作用):

在base R中,您将执行以下操作:

z <- merge(x, y, by="Date", all=TRUE)
z[z==0] <- NA
z <- na.locf(z)
z[is.na(z)] <- 0

z一种可能的解决方案是结合使用
data.table
na.locf
功能,该功能来自
zoo
包装:

# loading the needed packages
library(data.table)
library(zoo)

# converting x & y to datatables
setDT(x)
setDT(y)

# merge x & y into z
z <- merge(x, y, by="Date", all=TRUE) # this works in base R as well

# fill the NA's with the last observation
cols <- c("A","B","C","D") # in this specific case, you can also use: LETTERS[1:4]
z[, (cols) := lapply(.SD, na.locf, rule = 1, na.rm=FALSE), .SDcols= cols]
正如@Tensibai在评论中提到的那样,这个结果也可以在base R中实现(由于某种原因,最初在我的系统上不起作用):

在base R中,您将执行以下操作:

z <- merge(x, y, by="Date", all=TRUE)
z[z==0] <- NA
z <- na.locf(z)
z[is.na(z)] <- 0

z一种可能的解决方案是结合使用
data.table
na.locf
功能,该功能来自
zoo
包装:

# loading the needed packages
library(data.table)
library(zoo)

# converting x & y to datatables
setDT(x)
setDT(y)

# merge x & y into z
z <- merge(x, y, by="Date", all=TRUE) # this works in base R as well

# fill the NA's with the last observation
cols <- c("A","B","C","D") # in this specific case, you can also use: LETTERS[1:4]
z[, (cols) := lapply(.SD, na.locf, rule = 1, na.rm=FALSE), .SDcols= cols]
正如@Tensibai在评论中提到的那样,这个结果也可以在base R中实现(由于某种原因,最初在我的系统上不起作用):

在base R中,您将执行以下操作:

z <- merge(x, y, by="Date", all=TRUE)
z[z==0] <- NA
z <- na.locf(z)
z[is.na(z)] <- 0

z使用dplyr和一些函数的替代方法:

library(lubridate)
library(dplyr)

# dataset
x=data.frame(c("2000-01-01","2000-06-01","2001-01-01"),
             c("100","100","100"),
             c("200","200","200"), stringsAsFactors = F)
colnames(x)=c("Date","A","B")

y=data.frame(c("2000-01-05","2000-04-09"),
             c("10","0"),
             c("0","35"), stringsAsFactors = F)
colnames(y)=c("Date","C","D")

# update date columns
x$Date = ymd(x$Date)
y$Date = ymd(y$Date)

# function that replaces NAs with 0s
ff = function(x){x[is.na(x)]=0 
                 return(as.numeric(x))}

# function that updates zero elements with the previous ones
ff2 = function(x){

  for (i in 2:length(x)){x[i] = ifelse(x[i]==0, x[i-1], x[i])}

  return(x)

}

# create the full dataset
xy =
    x %>% 
    full_join(y, by="Date") %>% 
    arrange(Date)

xy

#         Date    A    B    C    D
# 1 2000-01-01  100  200 <NA> <NA>
# 2 2000-01-05 <NA> <NA>   10    0
# 3 2000-04-09 <NA> <NA>    0   35
# 4 2000-06-01  100  200 <NA> <NA>
# 5 2001-01-01  100  200 <NA> <NA>


  xy %>%
  group_by(Date) %>% 
  mutate_each(funs(ff)) %>%
  ungroup %>% 
  select(-Date) %>%
  mutate_each(funs(ff2)) %>%
  bind_cols(data.frame(Date=xy$Date)) %>%
  select(Date,A,B,C,D)

#           Date   A   B  C  D
#   1 2000-01-01 100 200  0  0
#   2 2000-01-05 100 200 10  0
#   3 2000-04-09 100 200 10 35
#   4 2000-06-01 100 200 10 35
#   5 2001-01-01 100 200 10 35
库(lubridate)
图书馆(dplyr)
#数据集
x=数据帧(c(“2000-01-01”、“2000-06-01”、“2001-01-01”),
c(“100”、“100”、“100”),
c(“200”、“200”、“200”),系数=F)
colnames(x)=c(“日期”、“A”、“B”)
y=数据帧(c(“2000-01-05”、“2000-04-09”),
c(“10”、“0”),
c(“0”,“35”),系数=F)
colnames(y)=c(“日期”、“c”、“D”)
#更新日期列
x$Date=ymd(x$Date)
y$日期=ymd(y$日期)
#将NAs替换为0的函数
ff=函数(x){x[is.na(x)]=0
返回(作为.numeric(x))}
#用以前的元素更新零元素的函数
ff2=函数(x){
对于(2中的i:length(x)){x[i]=ifelse(x[i]==0,x[i-1],x[i]))
返回(x)
}
#创建完整的数据集
xy=
x%>%
完全加入(y,by=“Date”)%>%
安排(日期)
xy
#日期A B C D
# 1 2000-01-01  100  200  
# 2 2000-01-05     10    0
# 3 2000-04-09      0   35
# 4 2000-06-01  100  200  
# 5 2001-01-01  100  200  
xy%>%
分组单位(日期)%>%
变异_-each(funs(ff))%>%
解组%>%
选择(-Date)%>%
变异_-each(funs(ff2))%>%
绑定列(data.frame(Date=xy$Date))%>%
选择(日期、A、B、C、D)
#日期A B C D
#   1 2000-01-01 100 200  0  0
#   2 2000-01-05 100 200 10  0
#   3 2000-04-09 100 200 10 35
#   4 2000-06-01 100 200 10 35
#   5 2001-01-01 100 200 10 35

使用dplyr和一些函数的替代方法:

library(lubridate)
library(dplyr)

# dataset
x=data.frame(c("2000-01-01","2000-06-01","2001-01-01"),
             c("100","100","100"),
             c("200","200","200"), stringsAsFactors = F)
colnames(x)=c("Date","A","B")

y=data.frame(c("2000-01-05","2000-04-09"),
             c("10","0"),
             c("0","35"), stringsAsFactors = F)
colnames(y)=c("Date","C","D")

# update date columns
x$Date = ymd(x$Date)
y$Date = ymd(y$Date)

# function that replaces NAs with 0s
ff = function(x){x[is.na(x)]=0 
                 return(as.numeric(x))}

# function that updates zero elements with the previous ones
ff2 = function(x){

  for (i in 2:length(x)){x[i] = ifelse(x[i]==0, x[i-1], x[i])}

  return(x)

}

# create the full dataset
xy =
    x %>% 
    full_join(y, by="Date") %>% 
    arrange(Date)

xy

#         Date    A    B    C    D
# 1 2000-01-01  100  200 <NA> <NA>
# 2 2000-01-05 <NA> <NA>   10    0
# 3 2000-04-09 <NA> <NA>    0   35
# 4 2000-06-01  100  200 <NA> <NA>
# 5 2001-01-01  100  200 <NA> <NA>


  xy %>%
  group_by(Date) %>% 
  mutate_each(funs(ff)) %>%
  ungroup %>% 
  select(-Date) %>%
  mutate_each(funs(ff2)) %>%
  bind_cols(data.frame(Date=xy$Date)) %>%
  select(Date,A,B,C,D)

#           Date   A   B  C  D
#   1 2000-01-01 100 200  0  0
#   2 2000-01-05 100 200 10  0
#   3 2000-04-09 100 200 10 35
#   4 2000-06-01 100 200 10 35
#   5 2001-01-01 100 200 10 35
库(lubridate)
图书馆(dplyr)
#数据集
x=数据帧(c(“2000-01-01”、“2000-06-01”、“2001-01-01”),
c(“100”、“100”、“100”),
c(“200”、“200”、“200”),系数=F)
colnames(x)=c(“日期”、“A”、“B”)
y=数据帧(c(“2000-01-05”、“2000-04-09”),
c(“10”、“0”),
c(“0”,“35”),系数=F)
colnames(y)=c(“日期”、“c”、“D”)
#更新日期列
x$Date=ymd(x$Date)
y$日期=ymd(y$日期)
#将NAs替换为0的函数
ff=函数(x){x[is.na(x)]=0
返回(作为.numeric(x))}
#用以前的元素更新零元素的函数
ff2=函数(x){
对于(2中的i:length(x)){x[i]=ifelse(x[i]==0,x[i-1],x[i]))
返回(x)
}
#创建完整的数据集
xy=
x%>%
完全加入(y,by=“Date”)%>%
安排(日期)
xy
#日期A B C D
# 1 2000-01-01  100  200  
# 2 2000-01-05     10    0
# 3 2000-04-09      0   35
# 4 2000-06-01  100  200  
# 5 2001-01-01  100  200  
xy%>%
分组单位(日期)%>%
变异_-each(funs(ff))%>%
解组%>%
选择(-Date)%>%
变异_-each(funs(ff2))%>%
绑定列(data.frame(Date=xy$Date))%>%
选择(日期、A、B、C、D)
#日期A B C D
#   1 2000-01-01 100 200  0  0
#   2 2000-01-05 100 200 10  0
#   3 2000-04-09 100 200 10 35
#   4 2000-06-01 100 200 10 35
#   5 2001-01-01 100 200 10 35

使用dplyr和一些函数的替代方法:

library(lubridate)
library(dplyr)

# dataset
x=data.frame(c("2000-01-01","2000-06-01","2001-01-01"),
             c("100","100","100"),
             c("200","200","200"), stringsAsFactors = F)
colnames(x)=c("Date","A","B")

y=data.frame(c("2000-01-05","2000-04-09"),
             c("10","0"),
             c("0","35"), stringsAsFactors = F)
colnames(y)=c("Date","C","D")

# update date columns
x$Date = ymd(x$Date)
y$Date = ymd(y$Date)

# function that replaces NAs with 0s
ff = function(x){x[is.na(x)]=0 
                 return(as.numeric(x))}

# function that updates zero elements with the previous ones
ff2 = function(x){

  for (i in 2:length(x)){x[i] = ifelse(x[i]==0, x[i-1], x[i])}

  return(x)

}

# create the full dataset
xy =
    x %>% 
    full_join(y, by="Date") %>% 
    arrange(Date)

xy

#         Date    A    B    C    D
# 1 2000-01-01  100  200 <NA> <NA>
# 2 2000-01-05 <NA> <NA>   10    0
# 3 2000-04-09 <NA> <NA>    0   35
# 4 2000-06-01  100  200 <NA> <NA>
# 5 2001-01-01  100  200 <NA> <NA>


  xy %>%
  group_by(Date) %>% 
  mutate_each(funs(ff)) %>%
  ungroup %>% 
  select(-Date) %>%
  mutate_each(funs(ff2)) %>%
  bind_cols(data.frame(Date=xy$Date)) %>%
  select(Date,A,B,C,D)

#           Date   A   B  C  D
#   1 2000-01-01 100 200  0  0
#   2 2000-01-05 100 200 10  0
#   3 2000-04-09 100 200 10 35
#   4 2000-06-01 100 200 10 35
#   5 2001-01-01 100 200 10 35
库(lubridate)
图书馆(dplyr)
#数据集
x=数据帧(c(“2000-01-01”、“2000-06-01”、“2001-01-01”),
c(“100”、“100”、“100”),
c(“200”、“200”、“200”),系数=F)
colnames(x)=c(“日期”、“A”、“B”)
y=数据帧(c(“2000-01-05”、“2000-04-09”),
c(“10”、“0”),
c(“0”,“35”),系数=F)
colnames(y)=c(“日期”、“c”、“D”)
#更新日期列
x$Date=ymd(x$Date)
y$日期=ymd(y$日期)
#将NAs替换为0的函数
ff=函数(x){x[is.na(x)]=0
返回(作为.numeric(x))}
#用以前的元素更新零元素的函数
ff2=函数(x){
对于(i in 2:length(x)){x[i]=ife