首页 > 解决方案 > 允许引用具有索引和名称的列的函数

问题描述

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

所以这个有效:

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"

我怎样才能解决这个问题?

标签: rfunctioncolumnsorting

解决方案


我们只需要遍历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

推荐阅读