r语言 - 在函数中将对象名称转换为字符串



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

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

在R中,如何获得对象'的名称后,它被发送到一个函数?

下面是listfunction的例子。

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包含stringapple

# $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)

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

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.

使用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)
#...
#...

purrrimap提供了相同的功能,您不需要显式传递名称。

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

最新更新