【问题标题】:dplyr - sum of multiple columns using regular expressionsdplyr - 使用正则表达式的多列总和
【发布时间】:2018-02-15 17:10:10
【问题描述】:

对于数据集 mtcars2

mtcars2 = mtcars
mtcars2 = mtcars2 %>% mutate(cyl9=cyl, disp9=disp, gear2=gear)

我想通过使用正则表达式捕获模式来获得一个新列,它是多列的总和。

这是一个解决方案,但是这是通过硬编码完成的

select(mtcars2, cyl9) + select(mtcars2, disp9) + select(mtcars2, gear2)

我尝试了类似的方法,但它给了我一个数字而不是一个向量

mtcars2 %>% select(matches("[0-9]")) %>% sum

请仅使用 dplyr 解决方案,因为稍后我需要将这些函数应用于 sql 表。

谢谢!

更新.. 我需要处理 sql 表的解决方案,数据设置如下..

mydb <- dbConnect(RSQLite::SQLite(), "")
dbWriteTable(mydb, "mt", mtcars)
mt.sql=tbl(mydb, "mt")
mt.sql = mt.sql %>% mutate(cyl9=cyl, disp9=disp, gear2=gear)

reduce()、rowSums()、rowwise() 在 sql 表上不起作用,我试过了,但它们给了我错误。

我试过了,

mt.sql %>% rowwise()

错误:is.data.frame(data) 不是 TRUE

mt.sql %>% select(matches("[0-9]")) %>% mutate(sum=rowSums(.))

UseMethod("escape") 中的错误: 没有适用于“escape”的方法应用于“c('tbl_dbi', 'tbl_sql', 'tbl_lazy', 'tbl')”类的对象

mt.sql %>% select(matches("[0-9]")) %>% reduce(`+`)

.x + .y 中的错误:二进制运算符的非数字参数

如果我将 mt.sql 切换到 mtcars2,它们都可以工作,所以我猜这是一个 sql 表问题。

【问题讨论】:

  • 你需要rowSums 而不是sum: mtcars2 %&gt;% select(matches("[0-9]")) %&gt;% rowSums()
  • @mt1022 添加为答案?
  • 感谢您的解决方案,但 rowSums 不适用于 sql 表。
  • 更新了..谢谢大家..
  • @RonakShah 这些解决方案仅适用于 dfs.. 我更新了我的帖子.. 谢谢

标签: r dplyr tidyr tidyverse


【解决方案1】:

我们可以使用tidyverse 选项

library(tidyverse)
mtcars2 %>%
      select(matches("[0-9]")) %>%
      reduce(`+`) #%>%
      #if needed to create a new column   
      #mutate(mtcars2, newcol = .)

#[1] 170.0 170.0 116.0 267.0 371.0 234.0 371.0 154.7 148.8 177.6 177.6 286.8
#[13] 286.8 286.8 483.0 471.0 451.0  86.7  83.7  79.1 127.1 329.0 315.0 361.0
#[25] 411.0  87.0 129.3 104.1 364.0 156.0 314.0 129.0

【讨论】:

  • 感谢您的解决方案,但 reduce() 不适用于 sql 表。请检查更新。谢谢!
【解决方案2】:

考虑到 SQL 约束阻止使用更简单和优雅的解决方案,例如 rowSumsreduce,我提供了一个更老套的答案,让我们回到更基本的 new_col = a + b + c + ... + n

library(dplyr)
library(stringr)

# get the variable names and form a text equation
col_eqn <- paste0(str_subset(colnames(mtcars), "[a-z]", collapse = " + ")

# run a normal  mutate function parsing and evaluating the equation
mtcars %>% mutate(new_col = eval(parse(text = col_eqn)))

# mpg cyl  disp  hp drat    wt  qsec vs am gear carb new_col
# 1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4 328.980
# 2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4 329.795
# 3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1 259.580
# 4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1 426.135
# 5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2 590.310
# 6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1 385.540
# 7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4 656.920
# 8  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2 270.980
# 9  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2 299.570
# 10 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4 350.460

【讨论】:

  • mt.sql %&gt;% select(matches("[0-9]")) %&gt;% names() 似乎没有给出名称.. 它出现的是“src”“ops”而不是名称。但是mt.sql %&gt;% select(matches("[0-9]")) 确实给出了名字..
  • 此时构造一个 SQL 字符串并以老式的方式执行不是更容易吗?
  • 尝试colnames 获取列名 - 与names 不同,它适用于小标题(普通和sql 风格)、数据框、数据表...
  • colnames 让您不必做整个头部/收集东西。使用stringr 包,它变成:col_eqn = paste0(str_subset(colnames(mt.sql),"[0-9]"),collapse=" + ")
猜你喜欢
  • 2015-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-06
  • 1970-01-01
  • 1970-01-01
  • 2015-09-25
  • 1970-01-01
相关资源
最近更新 更多