【发布时间】:2021-02-17 21:18:34
【问题描述】:
我仍然对 enquo 和 toString 的使用感到有些困惑。在下面的示例中,我基本上只是尝试过滤数据框并将最后的行求和。我真的不明白为什么 enquo 和 toString 对我想做的第一件事做同样的事情(过滤器 --> 选项 1 和 2 给出相同的结果)但不是我想做的第二件事(总和 -->选项 1 有效,但选项 2 给了我一个错误)。仅仅是因为我在 dplyr 管道中使用它吗?
library(dplyr)
library(tidyverse)
### define dataframe
dataframe_test <- data.frame(
column_test = c(100,99,99,90,89,50),
month_test = c("2020-09-01", "2020-09-01","2020-09-01", "2020-09-01","2020-10-01","2020-10-01")
)
test_function <- function(df, df_col_indicator, df_col_month, char_month) {
### define variables for enquo, ensym, toString
df_col_indicator_enquo <- enquo(df_col_indicator)
df_col_indicator_ensym <- ensym(df_col_indicator)
df_col_indicator_toString <- toString(df_col_indicator)
df_col_month_ensym <- ensym(df_col_month)
dataframe2 <- df %>%
filter(!!df_col_month_ensym == char_month) %>% # filter for month
slice_max(!!df_col_indicator_ensym, n = 3) %>% # slice top 3 observations
## two options for filter
# option 1
filter(!!df_col_indicator_ensym == df[2, df_col_indicator_toString]) # filter for observations with same observation as second row
# option 2
#filter(!!df_col_indicator_ensym == df[2, !!df_col_indicator_enquo])
## two options for sum
# option 1
bb <- sum(dataframe2[ , df_col_indicator_toString]) # sum up observations
# option 2
#bb <- sum(dataframe2[ , !!df_col_indicator_enquo])
return(bb)
}
test_function(df = dataframe_test, df_col_indicator = "column_test", df_col_month = "month_test" , char_month = "2020-09-01")
编辑:
谢谢大家的回答。呵呵,好吧我不得不承认这个例子有点愚蠢,但我在这里尽量保持简单。我最初的问题实际上是这个(见下文)。我基本上尝试选择一列的前 5 个数字。有三种不同的结果。 1)如果超过 5 个 ==100,那么我想将 5 个观察值随机存储在列表(指标)中,其他观察值在列表(星号)中。 2)如果不是所有的观察结果都是 ==100 但有关系(第 5、第 6 位具有相同的值),我想随机选择那些有关系的,然后再次将一些放入列表(指标)中,将其他观察放入列表(星号)中。 3)如果没有关系,只需选择前 5 个观察值。我现在的主要问题是,如果我想在最底部的循环(包含所有列)上运行我的函数。不知何故,我总是将第一行作为结果...我想我不明白如何在循环中正确设置函数的变量名...?
library(dplyr)
library(tidyverse)
remove(list = ls())
dataframe_test <- data.frame(
county_name = c("a", "b","c", "d","e", "f", "g", "h"),
column_test1 = c(100,100,100,100,100,100,50,50),
column_test2 = c(40,90,50,40,40,100,13,14),
column_test3 = c(100,90,50,40,30,40,100,50),
month = c("2020-09-01", "2020-09-01" ,"2020-09-01" ,"2020-09-01" ,"2020-09-01" ,"2020-09-01" ,"2020-08-01","2020-08-01"))
choose_top_5 <- function(df, df_col_indicator, df_col_month, char_month, numb_top, df_col_county) {
### enquo / ensym / deparse
df_col_indicator_enquo <- enquo(df_col_indicator)
df_col_indicator_ensym <- ensym(df_col_indicator)
df_col_month_ensym <- ensym(df_col_month)
df_col_month_enquo = enquo(df_col_month)
### filter month and top 5 observations
df_top <- df %>%
filter(!!df_col_month_ensym == char_month) %>%
slice_max(!!df_col_indicator_ensym, n = numb_top) %>%
select(!!df_col_county, !!df_col_month_ensym, !!df_col_indicator_ensym)
### if there are more than "numb_top" values and all equals to 100 --> randomly pick "numb_top"
if (nrow(df_top) > numb_top &
sum(df_top[ , df_col_indicator ]) == 100*nrow(df_top) ) {
## randomly pick "numb_top" out of all
random_shuffle <- df_top[sample(nrow(df_top)),]
indicator <- random_shuffle[1:numb_top,]
asterisk <- random_shuffle[(numb_top+1):nrow(random_shuffle),]
## return "numb_top" and put names of others in asterisk
return_list <- list(indicator, asterisk)
### if there are more than "numb_top" values but not all 100 (e.g. 100, 100, 100, 99, 99, 99)
## --> pick randomly 99 values
} else if (nrow(df_top) > numb_top) {
### filter for all observations that have the same value as "numb_top"
df_treshold <- df_top %>%
filter(!!df_col_indicator_ensym == df_top[numb_top, df_col_indicator])
## randomly shuffle the observations
random_shuffle <- df_treshold[sample(nrow(df_treshold)),]
## combine observations again an pick "numb_top"
combine <- rbind(df_top[1:(nrow(df_top)-nrow(df_treshold)), ], random_shuffle)
indicator <- combine[1:numb_top,]
asterisk <- combine[(numb_top+1):nrow(combine),]
## return "numb_top" and put names of others in asterisk
return_list <- list(indicator, asterisk)
### if there are not more than "numb_top" values
} else {
indicator <- df_top
asterisk <- NA
## return "numb_top", asterisk is NA
return_list <- list(indicator, asterisk)
}
return(return_list)
}
### function for 1 column
a=choose_top_5(df = dataframe_test, df_col_indicator = "column_test3",
df_col_month = "month", char_month = "2020-09-01", numb_top = 5,
df_col_county = "county_name")
a
### function over all columns and store in list
all_indicators <- c("column_test1","column_test2","column_test3")
my_list <- list()
for (i in all_indicators) {
my_list[[i]] <- choose_top_5(df = dataframe_test, df_col_indicator = i,
df_col_month = "month", char_month = "2020-09-01", numb_top = 5,
df_col_county = "county_name")
}
my_list
【问题讨论】: