【问题标题】:Convert object name to string in function在函数中将对象名称转换为字符串
【发布时间】:2021-10-19 04:18:54
【问题描述】:

我有一个listdata.frames。我想使用lapply 将每个data.frame 发送到function。在function 内部,我想检查data.framename 是否包含特定的string。如果有问题的string 存在,我想执行一系列操作。否则我想执行一系列不同的操作。我不知道如何检查string 是否存在于function 中。

我希望使用基础R。这似乎是一个可能的解决方案,但我无法让它工作:

In R, how to get an object's name after it is sent to a function?

这是一个示例list,后面是一个示例function

matrix.apple1 <- read.table(text = '
     X3   X4   X5
      1    1    1
      1    1    1
', header = TRUE)
matrix.apple2 <- read.table(text = '
     X3   X4   X5
      1    1    1
      2    2    2
', header = TRUE)
matrix.orange1 <- read.table(text = '
     X3   X4   X5
     10   10   10
     20   20   20
', header = TRUE)
my.list <- list(matrix.apple1  = matrix.apple1,
                matrix.orange1 = matrix.orange1,
                matrix.apple2  = matrix.apple2)

这个操作可以检查每个对象name是否包含stringapples 但我不确定如何在下面的function 中使用这些信息。

grepl('apple', names(my.list), fixed = TRUE)
#[1]  TRUE FALSE  TRUE

这是一个示例function。基于数小时的搜索和反复试验,我可能应该使用 deparse(substitute(x)),但到目前为止它只返回 x 或类似的东西。

table.function <- function(x) {

     # The three object names are:
     # 'matrix.apple1', 'matrix.orange1' and 'matrix.apple2'
     myObjectName <- deparse(substitute(x))
     print(myObjectName)

     # perform a trivial example operation on a data.frame
     my.table <- table(as.matrix(x))

     # Test whether an object name contains the string 'apple'
     contains.apple <- grep('apple', myObjectName, fixed = TRUE)

     # Use the result of the above test to perform a trivial example operation.
     # With my code 'my.binomial' is always given the value of 0 even though
     # 'apple' appears in the name of two of the data.frames.
     my.binomial <- ifelse(contains.apple == 1, 1, 0)

     return(list(my.table = my.table, my.binomial = my.binomial))
        
}

table.function.output <- lapply(my.list, function(x) table.function(x))

这些是print(myObjectName)的结果:

#[1] "x"
#[1] "x"
#[1] "x"

table.function.output

这是table.function 的其余结果,表明my.binomial 始终为0my.binomial 的第一个和第三个值应该是1,因为第一个和第三个data.framesnames 包含string apple

# $matrix.apple1
# $matrix.apple1$my.table
# 1 
# 6 
# $matrix.apple1$my.binomial
# logical(0)
# 
# $matrix.orange1
# $matrix.orange1$my.table
# 10 20 
#  3  3 
# $matrix.orange1$my.binomial
# logical(0)
# 
# $matrix.apple2
# $matrix.apple2$my.table
# 1 2 
# 3 3 
# $matrix.apple2$my.binomial
# logical(0)

【问题讨论】:

标签: r string list get lapply


【解决方案1】:

您可以重新设计您的函数以使用列表名称:

table_function <- function(myObjectName) {
  # The three object names are:
  # 'matrix.apple1', 'matrix.orange1' and 'matrix.apple2'
  myObject <- get(myObjectName)
  
  print(myObjectName)
  
  # perform a trivial example operation on a data.frame
  my.table <- table(as.matrix(myObject))
  
  # Test whether an object name contains the string 'apple'
  contains.apple <- grep('apple', myObjectName, fixed = TRUE)
  
  # Use the result of the above test to perform a trivial example operation.
  # With my code 'my.binomial' is always given the value of 0 even though
  # 'apple' appears in the name of two of the data.frames.
  my.binomial <- +(contains.apple == 1)
  
  return(list(my.table = my.table, my.binomial = my.binomial))
  
}


lapply(names(my.list), table_function)

返回

[[1]]
[[1]]$my.table

1 
6 

[[1]]$my.binomial
[1] 1


[[2]]
[[2]]$my.table

10 20 
 3  3 

[[2]]$my.binomial
integer(0)


[[3]]
[[3]]$my.table

1 2 
3 3 

[[3]]$my.binomial
[1] 1

如果你想保留列表名称,你可以使用

sapply(names(my.list), table_function, simplify = FALSE, USE.NAMES = TRUE)

而不是lapply

【讨论】:

    【解决方案2】:

    使用Map 并将列表数据及其名称传递给函数。更改您的函数以接受两个参数。

    table.function <- function(data, name) {
      
      # The three object names are:
      # 'matrix.apple1', 'matrix.orange1' and 'matrix.apple2'
      print(name)
      
      # perform a trivial example operation on a data.frame
      my.table <- table(as.matrix(data))
      
      # Test whether an object name contains the string 'apple'
      contains.apple <- grep('apple', name, fixed = TRUE)
      
      # Use the result of the above test to perform a trivial example operation.
      # With my code 'my.binomial' is always given the value of 0 even though
      # 'apple' appears in the name of two of the data.frames.
      my.binomial <- as.integer(contains.apple == 1)
      
      return(list(my.table = my.table, my.binomial = my.binomial))
    }
    
    Map(table.function, my.list, names(my.list))
    
    #[1] "matrix.apple1"
    #[1] "matrix.orange1"
    #[1] "matrix.apple2"
    #$matrix.apple1
    #$matrix.apple1$my.table
    
    #1 
    #6 
    
    #$matrix.apple1$my.binomial
    #[1] 1
    
    
    #$matrix.orange1
    #$matrix.orange1$my.table
    
    #10 20 
    # 3  3 
    
    #$matrix.orange1$my.binomial
    #integer(0)
    #...
    #...
    

    imappurrr 中提供相同的功能,您无需显式传递名称。

    purrr::imap(my.list, table.function)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-08
      • 1970-01-01
      • 2021-05-22
      相关资源
      最近更新 更多