我想从数据框中删除重复的行,仅适用于特定的列。可以通过distinct
获得:
data <- tibble(a = c(1, 1, 2, 2), b = c(3, 3, 3, 4), z = c(5,4,5,5))
filtered_data <- data %>% distinct(a, b, .keep_all = T)
dim(filtered_data)
# [1] 3 3
这(几乎)是我所需要的。但是,我的问题是我需要与
distinct
一起使用的列名将更改。因此,我有一个字符串gen
,其中包含我想用于distinct
函数的列的名称。他们需要被取消报价才能在管道中有用。我发现了使用as.name()
或eval(parse())
的建议。但是,这给了我不同的结果:gen <- c("a", "b")
filtered_data <- data %>% distinct(eval(parse(text = gen)), .keep_all = T)
dim(filtered_data)
# [1] 2 4
eval
似乎在过滤数据的次数上做了一些有趣的事情。 (并且,添加了一个额外的列。尽管我可以忍受……)所以,如何获得类似的结果,就像我曾经使用a,b
,而是使用变量来代替一样?其他信息
我实际上是通过读取数据框的列名来获得
gen
的:gen <- colnames(data)[1:2]
。如果我有办法将gen
转换为c(a, b)
,则@gymbrane建议的解决方案将是完美的。关键是要避免对列名进行硬编码。我尝试了类似gen <- noquotes(gen)
的操作,该操作在下面建议的rm_dup_rows
函数中没有给出错误,但是确实给出了不同的结果,给出了与我开始时相同的重复过滤...固定
我想我知道了。这可能很简单,而且我不确定结果是否需要每一步,但似乎可以通过将下面@gymbrane提供的功能与forloop中的
ensym
和quos
结合使用,同时将其添加到GlobalEnv
中的列表中来进行工作(编辑:不需要GlobalEnv):unquote_string <- function(string) {
out <- list()
i <- 1
for (s in string) {
t <- ensym(s)
out[i] <-dplyr::quos(!!t)
i <- i+1
}
return(out)
}
gen_quo <- unquote_string(gen)
filtered_data <- rm_dup_rows(data, gen_quo)
dim(filtered_data)
# [1] 3 3
最佳答案
如何创建函数并使用quosures。也许您正在寻找类似这样的东西...
rm_dup_rows <- function(data, ...){
vars = dplyr::quos(...)
data %>% distinct(!!! vars, .keep_all = T)
}
我相信这会返回您的要求
rm_dup_rows(data = data, a, b)
# A tibble: 3 x 3
a b z
<dbl> <dbl> <dbl>
1 3 5
2 3 5
2 4 5
rm_dup_rows(data, b, z)
# A tibble: 3 x 3
a b z
<dbl> <dbl> <dbl>
1 3 5
1 3 4
2 4 5
额外的
您可以稍微修改
rm_dup_rows
,然后使用quos
构造和向量。像这样的东西rm_dup_rows <- function(data, vars){
data %>% distinct(!!! vars, .keep_all = T)
}
# quos your column name vector
gen <- quos(a,z)
rm_dup_rows(data, gen)
# A tibble: 3 x 3
a b z
<dbl> <dbl> <dbl>
1 3 5
1 3 4
2 3 5
关于r - 取消引用字符串作为管道中的变量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51614933/