2017-09-07 62 views
1

對於數據集mtcars2dplyr - 多個列的總和使用正則表達式

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) 

減少(),rowSums(),橫行()不能在SQL表工作,香港專業教育學院試過這些,他們給我錯誤。

我試過,

mt.sql %>% rowwise() 

錯誤:is.data.frame(數據)是不是真

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

錯誤UseMethod( 「退出」): 因爲沒有適用的方法'逃離' 應用於類 「C( 'tbl_dbi', 'tbl_sql', 'tbl_lazy', 'TBL')」

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

錯誤.X +的對象。 y:二進制運算符的非數字參數

如果我將mt.sql切換到mtcars2,它們都工作,所以我想這是一個SQL表問題。

+2

你需要'rowSums',而不是'sum':'mtcars2%>%選擇(比賽( 「[0-9]」))%>%rowSums()' – mt1022

+0

@ mt1022添加爲一個答案? –

+0

感謝您的解決方案,但rowSums不工作在SQL表。 – user8542010

回答

1

考慮到SQL約束限制使用更簡單和優雅的解決方案,如rowSumsreduce,我提供了一個更劈-Y答案這使我們回更基本的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 
+0

'mt.sql%>%select(matches(「[0-9]」))%>%names()'似乎沒有給出名字..它出現爲「src」「ops」而不是名。但'mt.sql%>%select(matches(「[0-9]」))'確實給出了名字.. – user8542010

+0

現在構建一個SQL字符串並以舊式的方式執行它會不會更容易? – Spacedman

+0

這工作..謝謝..我會用這個,如果我找不到一個不太複雜的解決方案.. – user8542010

0

我們可以使用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 
+0

感謝您的解決方案,但減少()不能在sql表上工作.. 請檢查更新..謝謝! – user8542010