做一个管道函数
Make a pipeable function
关于使用 magrittr 管道在 R 中创建自定义函数,我遇到了一个我一直试图克服的小问题。基本上,我一直在尝试学习如何制作在通过管道时起作用的函数。虽然该函数用于汇总原始数据集的数据,但它不接受通过先前命令完成的修改。下面的示例:
TestData <- runif(1000, 1, 100)
TestID <- 1:1000
data01 <- data.frame(TestID, TestData) # Generate data to test the command on
custom_summary_cont2 <- function(DAT, var) {
DAT %>%
summarise(
mean = mean(var),
median = median(var),
sd = sd(var),
quant25 = unname(quantile(var, probs = 0.25)),
quant75 = unname(quantile(var, probs = 0.75)),
min = min(var),
max = max(var)
)
} # The custom function
现在 运行 此代码为:
summary <- custom_summary_cont2(data01, TestData)
或
summary <- data01 %>%
custom_summary_cont2(TestData)
两者都产生了我感兴趣的结果,但是当我在应用了上一个函数的情况下尝试传递自定义函数时,会出现复杂情况。例如:
summary <- data01 %>%
filter(TestData >50) %>%
custom_summary_cont2(TestData)
现在这段代码 returns 结果与我没有过滤功能的代码相同,我该如何编辑该功能以使其使用过滤命令的结果?
P.S 如果这是一个非常愚蠢的问题,我希望推荐一本介绍这些过程的好书。
这与管道无关。
您正在将 TestData
向量而不是列名称传递给您的函数。
引用列名需要强制非标准求值。
您可以通过将列引用包装在 {{ var }}
中来做到这一点,即:
custom_summary_cont2 <- function(DAT, var) {
DAT %>%
summarise(
mean = mean({{var}}),
median = median({{var}}),
sd = sd({{var}}),
quant25 = unname(quantile({{var}}, probs = 0.25)),
quant75 = unname(quantile({{var}}, probs = 0.75)),
min = min({{var}}),
max = max({{var}})
)
}
而不是var
,{{var}}
会给你一个结果。
custom_summary_cont2 <- function(DAT, var) {
DAT %>%
summarise(
mean = mean({{var}}),
median = median({{var}}),
sd = sd({{var}}),
quant25 = unname(quantile({{var}}, probs = 0.25)),
quant75 = unname(quantile({{var}}, probs = 0.75)),
min = min({{var}}),
max = max({{var}})
)
}
data01 %>%
filter(TestData >50) %>%
custom_summary_cont2(TestData)
mean median sd quant25 quant75 min max
1 74.95416 74.38507 14.66733 62.43108 87.26725 50.08382 99.92935
data01 %>%
filter(TestData >50) %>%
summarise(
mean = mean(TestData),
median = median(TestData),
sd = sd(TestData),
quant25 = unname(quantile(TestData, probs = 0.25)),
quant75 = unname(quantile(TestData, probs = 0.75)),
min = min(TestData),
max = max(TestData)
)
mean median sd quant25 quant75 min max
1 74.95416 74.38507 14.66733 62.43108 87.26725 50.08382 99.92935
关于使用 magrittr 管道在 R 中创建自定义函数,我遇到了一个我一直试图克服的小问题。基本上,我一直在尝试学习如何制作在通过管道时起作用的函数。虽然该函数用于汇总原始数据集的数据,但它不接受通过先前命令完成的修改。下面的示例:
TestData <- runif(1000, 1, 100)
TestID <- 1:1000
data01 <- data.frame(TestID, TestData) # Generate data to test the command on
custom_summary_cont2 <- function(DAT, var) {
DAT %>%
summarise(
mean = mean(var),
median = median(var),
sd = sd(var),
quant25 = unname(quantile(var, probs = 0.25)),
quant75 = unname(quantile(var, probs = 0.75)),
min = min(var),
max = max(var)
)
} # The custom function
现在 运行 此代码为:
summary <- custom_summary_cont2(data01, TestData)
或
summary <- data01 %>%
custom_summary_cont2(TestData)
两者都产生了我感兴趣的结果,但是当我在应用了上一个函数的情况下尝试传递自定义函数时,会出现复杂情况。例如:
summary <- data01 %>%
filter(TestData >50) %>%
custom_summary_cont2(TestData)
现在这段代码 returns 结果与我没有过滤功能的代码相同,我该如何编辑该功能以使其使用过滤命令的结果?
P.S 如果这是一个非常愚蠢的问题,我希望推荐一本介绍这些过程的好书。
这与管道无关。
您正在将 TestData
向量而不是列名称传递给您的函数。
引用列名需要强制非标准求值。
您可以通过将列引用包装在 {{ var }}
中来做到这一点,即:
custom_summary_cont2 <- function(DAT, var) {
DAT %>%
summarise(
mean = mean({{var}}),
median = median({{var}}),
sd = sd({{var}}),
quant25 = unname(quantile({{var}}, probs = 0.25)),
quant75 = unname(quantile({{var}}, probs = 0.75)),
min = min({{var}}),
max = max({{var}})
)
}
而不是var
,{{var}}
会给你一个结果。
custom_summary_cont2 <- function(DAT, var) {
DAT %>%
summarise(
mean = mean({{var}}),
median = median({{var}}),
sd = sd({{var}}),
quant25 = unname(quantile({{var}}, probs = 0.25)),
quant75 = unname(quantile({{var}}, probs = 0.75)),
min = min({{var}}),
max = max({{var}})
)
}
data01 %>%
filter(TestData >50) %>%
custom_summary_cont2(TestData)
mean median sd quant25 quant75 min max
1 74.95416 74.38507 14.66733 62.43108 87.26725 50.08382 99.92935
data01 %>%
filter(TestData >50) %>%
summarise(
mean = mean(TestData),
median = median(TestData),
sd = sd(TestData),
quant25 = unname(quantile(TestData, probs = 0.25)),
quant75 = unname(quantile(TestData, probs = 0.75)),
min = min(TestData),
max = max(TestData)
)
mean median sd quant25 quant75 min max
1 74.95416 74.38507 14.66733 62.43108 87.26725 50.08382 99.92935