【问题标题】:A function that allows referral to columns with both index and name允许引用具有索引和名称的列的函数
【发布时间】:2019-12-09 03:55:36
【问题描述】:

我试图通过允许索引和名称来创建一种更简单的方法来使用下面的函数来引用列。另见link

所以这个可行:

df <- data.table::fread("a b c d e f g h i j
                         1 2 3 4 5 6 7 8 9 10",
                                               header = TRUE)
columns <- c(1:8, "i", 9, "j")


col2num <- function(df, columns){
              nums <- as.numeric(columns)
              nums[is.na(nums)] <- which(names(df)==columns[is.na(nums)])
              return(nums)
            }

col2num(df, columns)
#> Warning in col2num(df, columns): NAs introduced by coercion
#>  [1]  1  2  3  4  5  6  7  8  9  9 10

这个也可以:

col2name <- function(df, columns){
              nums <- as.numeric(columns)
              nums[is.na(nums)] <- which(names(df)==columns[is.na(nums)])
              return(names(df)[nums])
            }

col2name(df, columns)
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "i" "j"
Warning message:
In col2name(df, columns) : NAs introduced by coercion

但是当我执行以下操作时,它不再起作用:

columns <- c(1:7, "j", 8, "i")
col2name <- function(df, columns){
              nums <- as.numeric(columns)
              nums[is.na(nums)] <- which(names(df)==columns[is.na(nums)])
              return(names(df)[nums])
            }

col2name(df, columns)
Error in nums[is.na(nums)] <- which(names(df) == columns[is.na(nums)]) : 
replacement has length zero

另外,这个不起作用:

columns <- c("a", "j", 8, "i")
col2name <- function(df, columns){
              nums <- as.numeric(columns)
              nums[is.na(nums)] <- which(names(df)==columns[is.na(nums)])
              return(names(df)[nums])
            }

col2name(df, columns)
[1] "a" "i" "h" "a"

我该如何解决这个问题?

【问题讨论】:

    标签: r function columnsorting


    【解决方案1】:

    我们只需要遍历columns:

    col2num <- function(df, columns){
      nums <- as.numeric(columns)
      nums[is.na(nums)] <- sapply(columns[is.na(as.numeric(columns))], 
                                  function(x) which(names(df) == x))
      return(nums)
    }
    
    col2name <- function(df, columns){
      nums <- as.numeric(columns)
      nums[is.na(nums)] <- sapply(columns[is.na(as.numeric(columns))], 
                                  function(x) which(names(df) == x))
      return(names(df)[nums])
    }
    
    columns1 <- c(1:8, "i", 9, "j")
    columns2 <- c(1:7, "j", 8, "i")
    
    suppressWarnings(col2name(df, columns1))
    #>  [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "i" "j"
    
    suppressWarnings(col2num(df, columns1))
    #>  [1]  1  2  3  4  5  6  7  8  9  9 10
    
    
    suppressWarnings(col2num(df, columns2))
    #>  [1]  1  2  3  4  5  6  7 10  8  9
    
    suppressWarnings(col2name(df, columns2))
    #>  [1] "a" "b" "c" "d" "e" "f" "g" "j" "h" "i"
    

    我使用suppressWarnings 来避免每次运行该函数时收到以下警告:

    Warning messages:
    1: In col2name(df, columns) : NAs introduced by coercion
    2: In lapply(X = X, FUN = FUN, ...) : NAs introduced by coercion
    

    【讨论】:

      【解决方案2】:

      另一个缺点是数据必须是data.frame 对象:

      indexr<- function(df, cols){
        to_match<-cols[grep("[A-za-z]",cols)]
        matched<-match(to_match,names(df))
        numerics <- as.numeric(c(setdiff(cols,to_match),matched))
      
      
        df[c(numerics)]
      }
      
      
      
       indexr(iris,c(1,"Sepal.Width"))
          Sepal.Length Sepal.Width
      1            5.1         3.5
      2            4.9         3.0
      3            4.7         3.2
      

      使用您的数据(缺点是我们返回到 data.frame)。可能会为此定义一个方法。

      data.table::setDF(df)
      indexr(df,columns)
        a b c d e f g h i i.1  j
      1 1 2 3 4 5 6 7 8 9   9 10
      

      编辑改为返回名称:

      indexr<- function(df, cols){
        to_match<-cols[grep("[A-za-z]",cols)]
        matched<-match(to_match,names(df))
        numerics <- as.numeric(c(setdiff(cols,to_match),matched))
      
      
        names(df[c(numerics)])
      }
      
      
       indexr(mtcars,c("mpg",5))
          [1] "drat" "mpg" 
      
      
        indexr(df,columns)
       [1] "a"   "b"   "c"   "d"   "e"   "f"   "g"   "h"   "i"   "i.1"
      [11] "j"  
      

      【讨论】:

        猜你喜欢
        • 2019-11-27
        • 2016-11-21
        • 2012-07-05
        • 2015-04-27
        • 1970-01-01
        • 2021-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多