【问题标题】:Matching Columns, Creating Loop in R匹配列,在 R 中创建循环
【发布时间】:2011-05-22 06:34:54
【问题描述】:

我有以下问题:

我有看起来像这样的数据框。我有价格,3 个 X 和 2 个 R。

Date    Name  Price  Interest
01.02.10 X  120     0.2
01.02.10 R  120     0.3
01.02.10 X  130     0.8
01.02.10 X  140     0.4
01.02.10 R  130     0.2
etc.

我想告诉 R 寻找价格相同的 X&R 对,然后删除其余的。所以这应该会产生:2 个 X 和 2 个 R(在这种情况下)。

Date    Name  Price  Interest
01.02.10 X  120     0.2
01.02.10 R  120     0.3
01.02.10 X  130     0.8
01.02.10 R  130     0.2
etc.

为了更清楚(希望如此):每个日期我都有很多不同的价格。每行有一个 X 或一个 R。每个日期有很多对,例如 X, Price = 120 & R, Price = 120 on Date 1. 但也有价格只匹配一个名称,例如有一个价格 = 140 仅用于名称= X。所以我希望 R 做的是:检查一个价格的匹配名称(即一个 X 和一个 R 存在相同的价格)并删除其余部分。实际上会产生相同数量的 X 和 R,因为我正在寻找对。

很抱歉无法发布我尝试过的内容。我什么都想不出来。

现在,到下一个问题: 如果成对存在,我想告诉 R 检查每一行。如果名称是 X,我希望它计算新价格,如果不只是打印现有价格。 我试过了

xx <- if(Name == "X"){Price + 100*interest} else print{Price}

但是没有用。

感谢帮助

干杯 丹妮

【问题讨论】:

  • 你需要更好地解释第一部分的逻辑。 “查找名称和价格对”对我来说没有任何意义。对于第二部分,您可以使用ifelse() 而不是if() ... else,因为前者是矢量化的。
  • 好的,谢谢。我想查找价格和名称的匹配项。所以我的数据框中有很多日期,名称为 X 或 R。对于每个日期,我也有价格观察。现在,对于每个日期,应该有一对 X&R 以一个价格,例如Date 1, x, price = 120 and Date 1, r, price = 120。还有其他不匹配的观察值,例如 Date 1, x, price = 140 而没有 Date 1, r, price = 140。我想告诉 R 检查匹配项(即 X&R 在每个日期具有相同的价格)并删除其余部分。现在清楚了吗?谢谢肖恩
  • 这使它成为一个合并问题。你 merge 在 Date 和 Name 上,然后比较(测试是否相等)x.Price 和 y.Price。
  • @DWin;好点,如果有点神秘。我花了一段时间来看看它是如何工作的。我已经编辑了我的答案,一步一步地展示了如何做到这一点。

标签: r loops matching


【解决方案1】:

编辑: @Dwin 对 Q 的评论有点神秘,由于 Q 不清楚,我在 Q 的第 1 部分的第一次尝试不正确,我会尝试赎回我自己尝试扩展 DWin 的评论:

[假设dat 包含您在Q 中引用的数据。] 首先,将dat 与其自身合并:

> foo <- merge(dat[, -4], dat, by.x = "Date", by.y = "Date")
> head(foo)
      Date Name.x Price.x Name.y Price.y Interest
1 01.02.10      X     120      X     120      0.2
2 01.02.10      X     120      R     120      0.2
3 01.02.10      X     120      X     130      0.2
4 01.02.10      X     120      X     140      0.2
5 01.02.10      X     120      R     130      0.2
6 01.02.10      R     120      X     120      0.2

接下来,取出Price.x == Price.y Name.x != Name.y所在的行

> (foo <- foo[with(foo, which(Price.x == Price.y & Name.x != Name.y)),])
       Date Name.x Price.x Name.y Price.y Interest
2  01.02.10      X     120      R     120      0.2
6  01.02.10      R     120      X     120      0.2
15 01.02.10      X     130      R     130      0.2
23 01.02.10      R     130      X     130      0.2

然后,去掉多余的列:

> (foo <- foo[, -(4:5)])
       Date Name.x Price.x Interest
2  01.02.10      X     120      0.2
6  01.02.10      R     120      0.2
15 01.02.10      X     130      0.2
23 01.02.10      R     130      0.2

最后,修正列名:

> names(foo) <- names(dat)
> foo
       Date Name Price Interest
2  01.02.10    X   120      0.2
6  01.02.10    R   120      0.2
15 01.02.10    X   130      0.2
23 01.02.10    R   130      0.2

第二件事可以使用ifelse来完成

with(dat, ifelse(Name == "X", Price + 100*Interest, Price))

这给了一些东西

> with(dat, ifelse(Name == "X", Price + 100*Interest, Price))
[1] 140 120 150 160 130

if() 不起作用的原因是 if() 只采用标量逻辑(单个 TRUEFALSE),而 Name == "X" 返回一个逻辑向量:

> with(dat, Name == "X")
[1]  TRUE FALSE  TRUE  TRUE FALSE

在这些情况下,ifelse() 是您的朋友。

【讨论】:

  • 嘿加文!感谢您的回答。第二部分完美运行。我很抱歉第一部分的描述不好。我不小心拿走了我的数据框的一个子集,其中兴趣实际上是相等的。但是,它确实会发生变化,并且不是恒定的。我尝试了独特的但实际上没有任何反应。我编辑了我的第一篇文章以使第一部分更清晰。干杯丹妮
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-15
  • 2023-03-22
  • 1970-01-01
相关资源
最近更新 更多