我试图将我对plyr的理解转移到dplyr,但我无法弄清楚如何按多列分组.
# make data with weird column names that can't be hard coded
data = data.frame(
asihckhdoydkhxiydfgfTgdsx = sample(LETTERS[1:3], 100, replace=TRUE),
a30mvxigxkghc5cdsvxvyv0ja = sample(LETTERS[1:3], 100, replace=TRUE),
value = rnorm(100)
)
# get the columns we want to average within
columns = names(data)[-3]
# plyr - works
ddply(data, columns, summarize, value=mean(value))
# dplyr - raises error
data %.%
group_by(columns) %.%
summarise(Value = mean(value))
#> Error in eval(expr, envir, enclos) : index out of bounds
Run Code Online (Sandbox Code Playgroud)
将plyr示例翻译成dplyr-esque语法我错过了什么?
编辑2017:Dplyr已更新,因此可以使用更简单的解决方案.查看当前选择的答案.
我想从带有动态过滤器的sql server中提取一些数据.我正在以下列方式使用伟大的R包dplyr:
#Create the filter
filter_criteria = ~ column1 %in% some_vector
#Connect to the database
connection <- src_mysql(dbname <- "mydbname",
user <- "myusername",
password <- "mypwd",
host <- "myhost")
#Get data
data <- connection %>%
tbl("mytable") %>% #Specify which table
filter_(.dots = filter_criteria) %>% #non standard evaluation filter
collect() #Pull data
Run Code Online (Sandbox Code Playgroud)
这段代码工作正常但现在我想以某种方式在我的表的所有列上循环它,因此我想将过滤器编写为:
#Dynamic filter
i <- 2 #With a loop on this i for instance
which_column <- paste0("column",i)
filter_criteria <- ~ which_column %in% some_vector
Run Code Online (Sandbox Code Playgroud)
然后使用更新的过滤器重新应用第一个代码.
不幸的是,这种方法没有给出预期的结果.实际上它没有给出任何错误,但是甚至没有将任何结果拉入R.特别是,我看了两个代码生成的SQL查询,并且有一个重要的区别.
第一个工作代码生成表单的查询:
SELECT ... FROM …Run Code Online (Sandbox Code Playgroud) 我正在编写一个函数,要求用户在函数调用中定义一个或多个分组变量.然后使用dplyr对数据进行分组,如果只有一个分组变量,它会按预期工作,但我还没有想出如何使用多个分组变量.
例:
x <- c("cyl")
y <- c("cyl", "gear")
dots <- list(~cyl, ~gear)
library(dplyr)
library(lazyeval)
mtcars %>% group_by_(x) # groups by cyl
mtcars %>% group_by_(y) # groups only by cyl (not gear)
mtcars %>% group_by_(.dots = dots) # groups by cyl and gear, this is what I want.
Run Code Online (Sandbox Code Playgroud)
我试着变成y和dots使用相同:
mtcars %>% group_by_(.dots = interp(~var, var = list(y)))
#Error: is.call(expr) || is.name(expr) || is.atomic(expr) is not TRUE
Run Code Online (Sandbox Code Playgroud)
如何使用> 1个变量名的用户定义输入字符串(如y示例中所示)使用dplyr对数据进行分组?
(这个问题在某种程度上与这个有关,但在那里没有回答.)
如果我不知道列名,但是想通过变量指定列名,我怎样才能将列名传递给dplyr?
例如,这工作:
require(dplyr)
df <- as.data.frame(matrix(seq(1:9),ncol=3,nrow=3))
df$group <- c("A","B","A")
gdf <- df %.% group_by(group) %.% summarise(m1 =mean(V1),m2 =mean(V2),m3 =mean(V3))
Run Code Online (Sandbox Code Playgroud)
但事实并非如此
require(dplyr)
someColumn = "group"
df <- as.data.frame(matrix(seq(1:9),ncol=3,nrow=3))
df$group <- c("A","B","A")
gdf <- df %.% group_by(someColumn) %.% summarise(m1 =mean(V1),m2 =mean(V2),m3 =mean(V3))
Run Code Online (Sandbox Code Playgroud) 我正在与R shine合作进行一些探索性数据分析.我有两个复选框输入,在一个复选框中我填充所有分类变量,其他都是数字变量.然后我在这两个选项上应用groupby如下.
var1 <- input$variable1 # Checkbox with categorical variables
var2 <- input$variable2 # Checkbox with numerical variables
v$data <- dataset %>%
group_by_(var1) %>%
summarize_(Sum = interp(~sum(x), x = as.name(var2))) %>%
arrange(desc(Sum))
Run Code Online (Sandbox Code Playgroud)
当只有1列的groupby时,哪种工作完全正常,但我想在多列上进行分组.当用户选择多个分类变量时,它会返回一个包含列名的数组.如何在dplyr groupby中传递此信息.
我经常需要在另一个函数内创建一个函数调用,然后进行评估.我倾向于使用eval(parse(text = "what_needs_to_be_done"))
,使用构造的文本paste0().但是,这并不是一种好方法.这是一个例子:
select_data <- function(x, A = NULL, B = NULL, C = NULL) {
kall <- as.list(match.call())
vars <- names(kall)[names(kall) %in% c("A", "B", "C")]
selection_criteria <- paste0(vars, " == ", kall[vars], collapse = ", ")
txt <- paste0("dplyr::filter(x, ", selection_criteria, ")")
res <- eval(parse(text = txt))
return(res)
}
DF <- data.frame(A = c(1,1,2,2,3,3), B = c(1,2,1,2,1,2), C = c(1,1,1,2,2,2))
select_data(DF, A = 2, C = 2)
Run Code Online (Sandbox Code Playgroud)
这只是一个例子,在大多数情况下,要构建的功能更复杂和更广泛.但是,该示例显示了一般问题.我现在做的首先paste0是函数调用,我在控制台输入它然后评估它的方式.
我已经篡改了与替代办法substitute,lazyeval, …
如何使用dplyr::arrange(dplyr::desc())并传入字符串作为列名?
这是一个示例数据集:
df <- data.frame(a = 1:3, b = 3:1)
Run Code Online (Sandbox Code Playgroud)
有效的例子:
df %>% dplyr::arrange(b)
df %>% dplyr::arrange_("b")
df %>% dplyr::arrange(dplyr::desc(b))
Run Code Online (Sandbox Code Playgroud)
但我似乎无法使用字符串既arrange和desc,这是两个版本,我想,不工作:
df %>% dplyr::arrange(dplyr::desc("b"))
df %>% dplyr::arrange_(dplyr::desc("b"))
Run Code Online (Sandbox Code Playgroud)
谢谢!
试图了解dplyr使用的非标准评估,但没有成功.我想要一个简短的函数,它返回一组指定变量的汇总统计数据(N,mean,sd,median,IQR,min,max).
我的功能的简化版本......
my_summarise <- function(df = temp,
to.sum = 'eg1',
...){
## Summarise
results <- summarise_(df,
n = ~n(),
mean = mean(~to.sum, na.rm = TRUE))
return(results)
}
Run Code Online (Sandbox Code Playgroud)
并使用一些虚拟数据运行它...
set.seed(43290)
temp <- cbind(rnorm(n = 100, mean = 2, sd = 4),
rnorm(n = 100, mean = 3, sd = 6)) %>% as.data.frame()
names(temp) <- c('eg1', 'eg2')
mean(temp$eg1)
[1] 1.881721
mean(temp$eg2)
[1] 3.575819
my_summarise(df = temp, to.sum = 'eg1')
n mean
1 100 NA
Run Code Online (Sandbox Code Playgroud)
计算N,但均值不计算,无法弄清楚原因.
最终,我希望我的功能更加通用,沿着...的路线.
my_summarise <- function(df = …Run Code Online (Sandbox Code Playgroud) 假设我有以下数据:
test_df <- data.frame(a=rnorm(100), b=rnorm(100))
Run Code Online (Sandbox Code Playgroud)
以下作品:
test_df %>%
summarise(y = mean(a))
Run Code Online (Sandbox Code Playgroud)
现在假设不是a我想传递一个字符串
string_outcome <- "a" # I want to use this
test_df %>%
summarise(y = mean(string_outcome))
Run Code Online (Sandbox Code Playgroud)
那行不通。我尝试使用,!!string_outcome但这也不起作用。我怎样才能解决这个问题?
这是一个玩具示例:
df <- data.frame(user=c('a','b'), rating=c(1,2), age=c(17,33))
rating <- function(df, var){x <- df %>% summarise(sum(var))}
rating(df,age)
Run Code Online (Sandbox Code Playgroud)
当我执行该函数时,我收到以下错误:
summarise_impl(.data,dots)出错:找不到对象'age'
如何将列名作为参数传递给函数?