【问题标题】:Match and replace columns of dataframe by multiple conditions通过多个条件匹配和替换数据框的列
【发布时间】:2017-01-05 21:38:45
【问题描述】:

干杯, 我有两个具有以下结构的数据框。

DF1:
Airlines           HeadQ      Date           Cost_Index
American           PHX        07-31-2016     220
American           ATL        08-31-2016     150
American           ATL        10-31-2016     150
Delta              ATL        10-31-2016     180
American           ATL        08-31-2017     200

第二个数据帧DF2的结构如下:

DF2:
Airlines           HeadQ      Date          
American           ATL        09-30-2016
Delta              ATL        03-31-2017

现在查找数据帧 DF1 和 DF2,我想将 DF1 更改为以下数据帧。

DF1:
Airlines           HeadQ      Date           Cost_Index
American           PHX        07-31-2016     220
American           ATL        08-31-2016     0
American           ATL        10-31-2016     150
Delta              ATL        10-31-2016     180
American           ATL        08-31-2017     200

条件是,从 DF2 中查找 DF1 的 Airlines 和 HeadQ,如果 DF1$Date

我尝试过,但没有成功:

DF1$Cost_Index <- ifelse(DF1$Airlines == DF2$Airlines & DF1$HeadQ == DF2$HeadQ 
        & DF1$Date < DF2$Date, 0, DF1$Cost_Index)


Warning:
1: In DF1$Airlines == DF2$Airlines : longer object
length is not a multiple of shorter object length". 
2: In<=.default(DF1$Date, DF2$Date) : longer object length is not a
multiple of shorter object length

DF1:
Airlines           HeadQ      Date           Cost_Index
American           PHX        07-31-2016     220
American           ATL        08-31-2016     0
American           ATL        10-31-2016     0
Delta              ATL        10-31-2016     0
American           ATL        08-31-2017     200

谁能指出我正确的方向?

注意:

str(DF1$Date): Date, format: "2016-10-31"
str(DF2$Date): Date, format: "2016-08-31"

【问题讨论】:

  • 在提出与有日期的数据相关的问题时,最好向我们提供您的原始数据,以便我们知道您在处理什么,您能提供吗?或者至少str(DF1)
  • 刚刚添加了数据框的结构:@Cyrus Mohammadian
  • 您遇到错误了吗?如果没有,你上面的代码产生了什么?
  • 它向我显示了以下警告:“警告消息:1:在 DF1$Airlines == DF2$Airlines 中:较长的对象长度不是较短对象长度的倍数”。 2:在&lt;=.default(DF1$Date, DF2$Date) 中:较长的对象长度不是较短对象长度的倍数
  • 请不要添加无关标签。

标签: r datetime dataframe dplyr


【解决方案1】:

使用 条件连接 功能(自 1.9.8 起),我会这样做:

require(data.table) # v1.9.8+
# convert to data.tables, and Date column to Date class.
setDT(df1)[, Date := as.Date(Date, format = "%m-%d-%Y")]
setDT(df2)[, Date := as.Date(Date, format = "%m-%d-%Y")]

df1[df2, on = .(Airlines, HeadQ, Date < Date), # find matching rows based on condition
      Cost_Index := 0L]                        # update column with 0 for those rows

df1
#    Airlines HeadQ       Date Cost_Index
# 1: American   PHX 2016-07-31        220
# 2: American   ATL 2016-08-31          0
# 3: American   ATL 2016-10-31        150
# 4:    Delta   ATL 2016-10-31        180

【讨论】:

  • 为什么DF1$Cost_Index2&lt;-ifelse(DF1$Airlines==DF2$Airlines &amp; DF1$HeadQ==DF1$HeadQ &amp; DF1$Date&lt;DF2$Date,0,DF1$Cost_Index) 不会产生相同的结果?相反,与2016-07-31 关联的Cost_Index 呈现为0(即2200 替换)
  • 我不是ifelse 的最大粉丝,但只是运行,例如,DF1$Airlines==DF2$Airlines 看看它给出了什么......提示:回收。您不能在这里简单地将两个相等/不相等的向量等同起来。对于DF2 中的每一行,您必须获取DF1 中的所有匹配行。
  • 啊!好的,我明白了,在这种情况下,这种方法怎么样:DF1$Cost_Index[DF1$Airlines==DF2$Airlines &amp; DF1$HeadQ ==DF2$HeadQ &amp; DF1$Date&lt;DF2$Date]&lt;-0 也不会产生正确的输出
  • 用 data.table 屏蔽了其他几个函数,例如 reshape2 中的“melt”,lubridate 中的几个函数。
  • data.table 具有用于 melt/dcast 的 data.table 方法和日期/时间方法(与 lubridate 重叠)。最简单的解决方案是在加载其他两个包之前加载data.table。或者使用lubridate::reshape2:: 并明确。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-14
  • 2022-07-06
  • 1970-01-01
  • 2021-02-20
  • 1970-01-01
相关资源
最近更新 更多