我有一个这样的数据集:
dataf <- data.frame(
Name = c("Alice", "Bob", "Charlie", "Alice", "Bob", "Charlie"),
Age = c(25, 30, 5, 35, 35, 15),
Score = c(95, 88, 76, 95, 88, 76)
)
我可以用下面的方法来排序:(按姓名降序,按年龄升序)。没问题.
with(dataf, dataf\[order(-as.numeric(as.factor(Name)), as.numeric(as.factor(Age))), \])
然而,我想写一个函数,这样我就可以通过不同数量的变量将它重新用于其他数据集。
比如说,我的函数有两个输入:数据集和OrderBy
其中“dataset”是数据集的名称,
此格式的OrderBy:
c("var1 dir1", "var2 dir2",...)
在我的最后一个示例中,OrderBy是c(“Name -",“Age +”),因此该函数可以生成如下输出
with(df, df\[order(-as.numeric(as.factor(Name)), as.numeric(as.factor(Age))), \])
请注意,第一个as.numeric之前有一个减号,表示按Name降序,第二个as.numeric没有符号,表示按Age升序。
实际上,我几乎做到了以下几点:(我使用的是Base R,没有dplyr包)
Sorting_Func <- function(df, sorting_info) {
print(df)
variable_names <- gsub("[+-]", "", sorting_info)
directions <- ifelse(grepl("-", sorting_info), "-", "")
# Create sorting expressions
sorting_exprs <- sapply(1:length(variable_names), function(i) {
expr <- paste0(directions[i], "as.numeric(as.factor(", variable_names[i], "))")
return(expr)
})
# Combine the sorting expressions into a single string
sorting_string <<- noquote(paste0(sorting_exprs, collapse = ", "))
print("sorting_string")
print(sorting_string)
tmp<-with(df, df[order(sorting_string), ])
return(df)
}
Sorting_Func(dataf, c("Name +", "Age -") )
你可以看到我的“sorting_string”是正确的,但是它没有在order()中被评估/使用,并且输出不正确。
但是,如果我将sorting_string的值复制到order()中,如下所示:
with(dataf, dataf[order(as.numeric(as.factor(Name )), -as.numeric(as.factor(Age ))), ])
它工作正常。
有人知道为什么以及如何解决这个问题吗?
或者有人知道是否有一个现有的函数,我可以使用它来实现我在这里所做的事情吗?
输入数据示例
姓名年龄评分
1爱丽丝25 95
2 Bob 30 88
3查理5 76
4爱丽丝35 95
5鲍勃35 88
6查理15 76
按姓名升序排序,按年龄(姓名内)降序排序。
姓名年龄评分
4爱丽丝35 95
1爱丽丝25 95
5鲍勃35 88
2 Bob 30 88
6查理15 76
3查理5 76
2条答案
按热度按时间chhqkbe11#
考虑到我的意见,我建议这个更简单的实现:
我认为你的实现不起作用的原因是因为你从来没有
eval(parse())
粘贴在一起的表达式。但是,将代码粘贴在一起并执行它几乎从来都不是一个好主意,而且很少需要。在这种情况下,我们可以使用lapply
来生成list
,使用do.call
来调用order()
,并使用列表中的元素作为参数。它更简单,更少的bug。使用像
xtfrm
这样的内置实用函数也可以使代码更加健壮。站在R核心的肩膀上,这段代码应该很好,很高效,可以处理各种各样的输入数据类型。mdfafbf12#
您可以使用一点字符串解析来让该函数处理所需的输入格式。请注意,这无论如何都不是惯用的R语言,您可能会更好地遵循Gregor的建议。此函数比长,因为允许任意字符串输入时需要进行必要的错误处理,这是支持不同输入格式的另一个原因。
也就是说,只要没有一个列名以
+
或-
结尾,下面的代码就可以工作(尽管它也可以扩展以处理这些情况)。:这给了我们
创建于2023-09-22使用reprex v2.0.2