我想将特定位置(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)
答案 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