【问题标题】:How to extract certain values from one column based on restrictions fulfilled in another column?如何根据另一列中满足的限制从一列中提取某些值?
【发布时间】:2017-10-10 14:01:19
【问题描述】:

我正在尝试在 r 中构建一个代码,它将根据来自不同列中的行的值从一列中的某些行返回值。

更具体地说,我有以下数据集 (BTM):

Date       CompanyName   MarketValue  BookValue    BookToMarket
31.12.87   Bure Equity   2182000      2260267      
31.01.88   Bure Equity   2102000      1950267
29.02.88   Bure Equity   2182000      2550267
...
31.07.88   Bure Equity   2022000      2980267  BookValue Des87/MarketValueJuly88
31.08.88   Bure Equity   2162000      2650267
30.09.88   Bure Equity   2272000      2390267  BookValue Des87/MarketValueSept88
31.10.88   Bure Equity   2122000      2650267
30.11.88   Bure Equity   2382000      2350267
31.12.88
31.12.87   H&M           2182000      2650267
31.01.88   H&M           2102000      2650267
29.02.88   H&M           2182000      2650267

(这只是总数据集的一小部分摘录;我有大约 1000 家公司和每家公司 30 年的月度数据)

我需要计算每个公司在每个日期内的账面市值比。但是,在计算 1988 年 7 月到 1989 年 6 月的账面市值比时,我需要使用 1987 年 12 月的账面价值。这意味着我需要让 R 理解在计算账面市值比时1988 年 7 月至 1989 年 6 月期间; R 需要使用 1987 年 12 月的账面价值,同时使用给定月份的市场价值。

换句话说,我需要编写以下代码:获取“Bure Equity”的账面价值,如果它对应于 87 年 12 月 31 日。然后将这个账面价值除以“Bure Equity”从 88 年 7 月到 89 年 6 月的市场价值。
(这需要进行编码,使其适用于每家公司和 1987-2016 年期间)。

为了做到这一点,我尝试在 r 中输入以下内容:

BTM$"Book to Market" <- ((BTM$"Book Value" | "Date"=="1987-12")/BTM$"Market Value")

这给了我一些价值,但不出所料,不是正确的。

理想情况下,我想要一个公式,如果它对应于“日期”列中的 12 月 87 日、12 月 88 日、12 月 89 日等,则可以为我提供“账面价值”列中的值。

然后我需要 R 将选择的账面价值除以接下来几个月 7 月 88 日至 6 月 89 日、7 月 89 日至 6 月 90 日等的不同市场价值。

R 将公司彼此分开也很重要。例如,我需要 R 理解它只能将 H&M 97 年 12 月的账面价值除以 H&M 88 年 7 月的市场价值(而不是例如 Bure Equity)。

有没有人知道我该如何完成这项工作?

我很感激我能得到的任何提示。

【问题讨论】:

  • 我认为您可以使用 dplyr 来实现这一点。您能否发布一个可重复的数据示例,以便我们可以玩耍? dput(head(BTM)) 应该可以工作。
  • 在你的例子中,你所有的BookValue都是一样的,你能提供你有不同BookValue的数据吗?
  • 我现在已经更改了 BookValue 的 :)
  • 去掉空行可以吗?

标签: r rows


【解决方案1】:

您可以使用dplyrlubridate 做到这一点:

library(lubridate)
library(dplyr)

df %>%
  mutate(Date = dmy(Date)) %>%
  group_by(CompanyName) %>%
  filter(month(Date) == 12) %>%
  inner_join(df, by = "CompanyName") %>%
  select(Date = Date.y, CompanyName, MarketValue = MarketValue.y, BookValue = BookValue.x) %>%
  mutate(BookToMarket = BookValue/MarketValue,
         Date = dmy(Date)) 

结果:

# A tibble: 12 x 5
# Groups:   CompanyName [3]
         Date CompanyName MarketValue BookValue BookToMarket
       <date>      <fctr>       <int>     <int>        <dbl>
 1 1987-12-31  BureEquity     2182000   2260267    1.0358694
 2 1988-01-31  BureEquity     2102000   2260267    1.0752935
 3 1988-02-29  BureEquity     2182000   2260267    1.0358694
 4 1988-07-31  BureEquity     2022000   2260267    1.1178373
 5 1988-08-31  BureEquity     2162000   2260267    1.0454519
 6 1988-09-30  BureEquity     2272000   2260267    0.9948358
 7 1988-10-31  BureEquity     2122000   2260267    1.0651588
 8 1988-11-30  BureEquity     2382000   2260267    0.9488946
 9 1988-12-31                      NA        NA           NA
10 1987-12-31         H&M     2182000   2650267    1.2146045
11 1988-01-31         H&M     2102000   2650267    1.2608311
12 1988-02-29         H&M     2182000   2650267    1.2146045

数据:

df = read.table(text = "Date       CompanyName   MarketValue  BookValue   
                31.12.87   BureEquity   2182000      2260267      
                31.01.88   BureEquity   2102000      1950267
                29.02.88   BureEquity   2182000      2550267
                31.07.88   BureEquity   2022000      2980267  
                31.08.88   BureEquity   2162000      2650267
                30.09.88   BureEquity   2272000      2390267  
                31.10.88   BureEquity   2122000      2650267
                30.11.88   BureEquity   2382000      2350267
                31.12.88
                31.12.87   H&M           2182000      2650267
                31.01.88   H&M           2102000      2650267
                29.02.88   H&M           2182000      2650267", header = TRUE, fill = TRUE)

【讨论】:

  • 嗨。谢谢您的回答!但是,它似乎不起作用:> BTM %>% + mutate(Date = dmy(Date)) %>% + group_by("Company Name") %>% + filter(month(Date) == 12) % >% + inner_join(BTM, by = "Company Name") %>% + select(Date = Date.y, "Company Name", "Market Value" = MarketValue.y, "Book Value" = BookValue.x) % >% + mutate(BookToMarket = "账面价值"/"Market Value", + Date = dmy(Date)) overscope_eval_next(overscope, expr) 中的错误:找不到对象'MarketValue.y' 另外:警告消息:所有格式解析失败。未找到任何格式。
  • 我需要在 BookValue 和 MarketValue 等之间添加一个空格,因为这些列分别称为 Book Value、Market Value 等。这是我对您的代码所做的唯一更改(加上将 df 替换为 BTM,因为 BTM 是我的数据框的名称),但是,我总是收到一条错误消息。你可能知道问题可能是什么?
  • 这是我输入的代码:BTM %>% mutate(Date = dmy(Date)) %>% group_by("Company Name") %>% filter(month(Date) == 12) %>% inner_join(BTM, by = "Company Name") %>% select(Date = Date.y, "Company Name", "Market Value" = MarketValue.y, "Book Value" = BookValue.x) %>% mutate(BookToMarket = "账面价值"/"市场价值", Date = dmy(Date))
  • @Marthe 好吧,这个问题可能与您实际拥有的数据有关。不要复制和粘贴表格,而是将dput(BTM) 的输出复制并粘贴到您的问题中。这会保留每列的数据类型。如果BTM 太大,则创建一个子集然后duput(subset)。旁注,在进行故障排除时,您可以从管道顶部开始并逐步添加新管道,然后查看是否出现错误。这样您就可以准确地知道哪一步出错了。
猜你喜欢
  • 2018-07-15
  • 1970-01-01
  • 1970-01-01
  • 2023-02-18
  • 2022-11-18
  • 2017-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多