R 按传递给函数的列名对数据帧进行排序

R 按传递给函数的列名对数据帧进行排序,r,R,我想写一个按列排序的函数。当然,这个基本练习之前已经被问过很多次了,但是解决方案建议要么使用,因此不能用在函数(还有,和)中,也不能用在require中,这会导致脆性编程(还有) 我所寻找的显然被称为“参考透明度”。好的但至少在本例中,采用这个术语将导致定义和区分程序中的文字。因此,MWE是最好的 函数体sort.by.column应该包含什么,以便 sort.by.column <- function(df, column.name) { ## ?? } df1 <- d

我想写一个按列排序的函数。当然,这个基本练习之前已经被问过很多次了,但是解决方案建议要么使用,因此不能用在函数(还有,和)中,也不能用在require中,这会导致脆性编程(还有)

我所寻找的显然被称为“参考透明度”。好的但至少在本例中,采用这个术语将导致定义和区分程序中的文字。因此,MWE是最好的

函数体
sort.by.column
应该包含什么,以便

sort.by.column <- function(df, column.name) {
    ## ??
}

df1 <- data.frame(Instrument=c("B","A"),
                  Value=c(3,2))
df2 <- data.frame(Device=c("D","C"),
                  Value=c(5,4))
column.name.1 <- "Instrument"
sorted1 <- sort.by.column(df1, column.name.1)
column.name.2 <- "Device"
sorted2 <- sort.by.column(df2, column.name.2)

sort.by.column您可以使用
order
将函数
sort.by.column
编写为:

sort.by.column <- function(df, column.name) {
  df[order(df[,column.name]),]
}    

#Lets test the function

sort.by.column(df1, "Value")
#   Instrument Value
# 2          B     2
# 1          A     3
sort.by.column(df2, "Value")
#   Device Value
# 2      D     4
# 1      C     5

sort.by.column(df1, "Instrument")
#   Instrument Value
# 1          A     3
# 2          B     2
sort.by.column(df2, "Device")
#   Device Value
# 1      C     5
# 2      D     4
返回数据帧的1列子集。表情

df[,col.name]
order(df[,col.name])
对该子集进行排序,返回行的索引。最后

df[order(df[,col.name]),]

返回数据帧的行子集,行索引按计算顺序排列。

这里有一个包装器,用于
dplyr::arrange
获取文本:

library(dplyr)
sort.by.column <- function(df, column.name) {
  col <- sym(column.name)
  arrange(df, !!col)
}
库(dplyr)

sort.by.column我在这里收集解决方案以确认、比较和理解

s1 <- function(df, column.name) {
    #library(dplyr)    
    dplyr::arrange_(df, column.name)
}


# version which does not require a `library(dplyr)` call
a50915367 <- function(df, column.name) {
    # library(dplyr)
    col <- rlang::sym(column.name) # dplyr::sym also works
    dplyr::arrange(df, rlang::`!!`(col))    
}

library(dplyr) # required before function
a50915367 <- function(df, column.name) {
    col <- sym(column.name) 
    arrange(df, !!col)    
}

a50915313 <- function(df, column.name) {
    df[order(df[,column.name]),]
}

f <- function(sorting.function) {
    df1 <- data.frame(Instrument=c("B","A"), Value=c(3,2))
    df2 <- data.frame(Device=c("D","C"), Value=c(5,4))

    column.name.1 <- "Instrument"
    sorted1 <- sorting.function(df1, column.name.1)
    column.name.2 <- "Device"
    sorted2 <- sorting.function(df2, column.name.2)

    ret.list <- list(r1=sorted1,
                     r2=sorted2)
    ret.list
}

g <- function() {
    cat("----------------1----------------\n")
    print(f(s1))
    cat("----------------a50915367----------------\n")
    print(f(a50915367))
    cat("----------------a50915313----------------\n")
    print(f(a50915313))
}

g()

s1使用
dplyr::arrange有什么问题?i、 e.
sorted1@MelissaKey我也认为
arrange\u
会很好地发挥作用,直到我读到
arrange\u
被弃用。不赞成(
arrange
/
arrange\uu
)对的更一般性似乎有些奇怪,因此我想弄清楚这一切的逻辑。我知道它是可行的,但我想知道为什么。双重否定已经很清楚了,但是把符号,即
sym
函数的结果,当作布尔值处理有什么意义呢?实际上,
未用作双重否定。有关这方面的详细介绍,请参阅。
rlang
程序包(导入到
dplyr
)是
arrange\uuu
和其他类似变体的替代品。您能确认我刚才添加到您答案中的解释是准确的,还是提供一个?@Vrokipal您对答案的描述是正确的。我也批准了你的编辑。此外,我不建议对此函数使用任何
,因为使用base=R可以实现此结果。在函数内调用库通常是不好的做法。我编辑了您的代码,以反映如何在不首先调用
库的情况下调用这些函数。
library(dplyr)
sort.by.column <- function(df, column.name) {
  col <- sym(column.name)
  arrange(df, !!col)
}
s1 <- function(df, column.name) {
    #library(dplyr)    
    dplyr::arrange_(df, column.name)
}


# version which does not require a `library(dplyr)` call
a50915367 <- function(df, column.name) {
    # library(dplyr)
    col <- rlang::sym(column.name) # dplyr::sym also works
    dplyr::arrange(df, rlang::`!!`(col))    
}

library(dplyr) # required before function
a50915367 <- function(df, column.name) {
    col <- sym(column.name) 
    arrange(df, !!col)    
}

a50915313 <- function(df, column.name) {
    df[order(df[,column.name]),]
}

f <- function(sorting.function) {
    df1 <- data.frame(Instrument=c("B","A"), Value=c(3,2))
    df2 <- data.frame(Device=c("D","C"), Value=c(5,4))

    column.name.1 <- "Instrument"
    sorted1 <- sorting.function(df1, column.name.1)
    column.name.2 <- "Device"
    sorted2 <- sorting.function(df2, column.name.2)

    ret.list <- list(r1=sorted1,
                     r2=sorted2)
    ret.list
}

g <- function() {
    cat("----------------1----------------\n")
    print(f(s1))
    cat("----------------a50915367----------------\n")
    print(f(a50915367))
    cat("----------------a50915313----------------\n")
    print(f(a50915313))
}

g()