几列相乘

时间:2019-05-28 20:08:19

标签: r dplyr mutate

我想将特定位置(0-100、0-12等,各个变量列)的某些计数乘以存在计数的天数(天)

以下是我的数据示例:

df <- structure(list(month = c("Apr", "Apr", "Aug", "Aug", "Aug", "Sep"
), Year = c(2018, 2018, 2018, 2018, 2018, 2018), First = 
 structure(c(17995, 
 17998, 17750, 17758, 17770, 17778), class = "Date"), Last = 
 structure(c(17999, 
 17998, 17750, 17761, 17771, 17778), class = "Date"), days = c(5, 
 1, 1, 4, 2, 1), `0-100` = c(1, 0, 1, 1, 1, 1), `0-12` = c(0, 
 0, 1, 1, 1, 1), `0-25` = c(1, 1, 1, 1, 1, 1), `0-50` = c(1, 0, 
1, 1, 1, 1)), row.names = c(NA, -6L), class = c("tbl_df", "tbl", 
 "data.frame"))

所以我在想一些类似的事情:

df2 <- df %>%
  mutate("0-100b" = days * "0-100", "0-12b" = days * "0-12", "0-25b" = days * "0-25", "0-50b" = days * "0-25")

其中一个似乎不起作用,但是两个都必须比写出每个乘法还要更简洁……如果我有更多的列,这似乎有点乏味。

确定编辑列名:

colnames(df) <- c("month", "Year", "First", "Last" , "days", "V", "I", 
"II", "III")

df2 <- df %>%
mutate(Vb = days * V, Ib = days * I, IIb = days * 
       II, IIIb = days * III)

1 个答案:

答案 0 :(得分:1)

就像我在上面说的那样,您可以通过将其包装在反引号中来选择名称不正确的列。命名规则的放置位置之一是基本函数make.names的文档中。

使用不正确名称的最简单解决方案是仅使用有效名称创建数据,但实际上,并非总是这样。有几种方法可以将名称更改为有效名称。前述的make.names通过字符向量来实现。

如果您在更大的管道工作流程中工作,则可以将rename_all与一些字符串操作函数一起使用,以进行以下操作:1)转换为小写,2)将-替换为_,和3)在任何前导数字前加x。您还可以使用janitor::clean_names,它清除数据框中的所有名称。

library(dplyr)

df %>%
  rename_all(~tolower(.) %>% 
               stringr::str_replace_all(., "\\-", "_") %>%
               stringr::str_replace("^\\b(?=\\d)", "x"))
# omitted: same names as below

使用干净的名称,您可以使用mutate_at,选择列,然后将其传递给要乘以days的函数。如果您使用命名列表,则会在名称后面添加名称以创建新列,而不是替换它们。

df %>%
  janitor::clean_names() %>%
  mutate_at(vars(x0_100:x0_50), list(b = ~. * days))
#> # A tibble: 6 x 13
#>   month  year first      last        days x0_100 x0_12 x0_25 x0_50 x0_100_b
#>   <chr> <dbl> <date>     <date>     <dbl>  <dbl> <dbl> <dbl> <dbl>    <dbl>
#> 1 Apr    2018 2019-04-09 2019-04-13     5      1     0     1     1        5
#> 2 Apr    2018 2019-04-12 2019-04-12     1      0     0     1     0        0
#> 3 Aug    2018 2018-08-07 2018-08-07     1      1     1     1     1        1
#> 4 Aug    2018 2018-08-15 2018-08-18     4      1     1     1     1        4
#> 5 Aug    2018 2018-08-27 2018-08-28     2      1     1     1     1        2
#> 6 Sep    2018 2018-09-04 2018-09-04     1      1     1     1     1        1
#> # … with 3 more variables: x0_12_b <dbl>, x0_25_b <dbl>, x0_50_b <dbl>

在这种情况下,也可以通过正则表达式选择列:

df %>%
  janitor::clean_names() %>%
  mutate_at(vars(matches("^x\\d")), list(b = ~. * days))
# same output as above