首页 > 解决方案 > 使用 lapply 时功能的工作方式不同

问题描述

首先 - 我为这个措辞糟糕的问题道歉,如果你有任何更合适的建议,我会全力以赴!

我编写了一个函数,它根据对象的调用向我的 df 添加一个新变量。例如,我有x_data,当我将它放入我的函数时,x_or_y会创建一个名为的新变量,所有条目都显示“x”。你猜对了 - 还有一个y_data, 当插入函数时它会创建相同的变量x_or_y并用“y”填充它

但是,当我有一个 dfs ( x_dataand y_data) 列表并且我使用lapply()该列表时,我遇到了一些问题-它只是为所有人返回相同的字母。请参阅下面的示例。

例子:

set.seed(123)
x_data <- data.frame(A = rnorm(20),
                 B = rnorm(20))
y_data <- data.frame(A = rnorm(20),
                 B = rnorm(20))

“x 或 y”的函数:

add_x_or_y  <- function(z) {
  z$x_or_y <- ifelse(grepl(pattern = "x", 
                                 deparse(substitute(z)), fixed = TRUE), 
                           "x", "y")
  z
}

所以自己尝试这个功能:

head(add_x_or_y(x_data),3)

            A          B x_or_y
1 -0.56047565 -1.0678237      x
2 -0.23017749 -0.2179749      x
3  1.5587083 -1.0260044       x

head(add_x_or_y(y_data),3)

           A          B x_or_y
1 -0.6947070  0.3796395      y
2 -0.2079173 -0.5023235      y
3 -1.2653964 -0.3332074      y

好的,这样行得通 - 但在现实生活中,我需要通过该功能执行大约 20 个不同的 dfs。每次写都浪费了很多空间,所以让我们列个清单并使用lapply().

x_y_list <- list(x_data = x_data,
                 y_data = y_data)
x_y_list <- lapply(x_y_list, add_x_or_y)

head(x_y_list$x_data,3)
           A          B x_or_y
1 -0.5604756 -1.0678237      y
2 -0.2301775 -0.2179749      y
3  1.5587083 -1.0260044      y

head(x_y_list$y_data,3)
           A          B x_or_y
1 -0.6947070  0.3796395      y
2 -0.2079173 -0.5023235      y
3 -1.2653964 -0.3332074      y

它没有用!:( 第一个x_or_y变量中应该有“x”。我确信这是一个非常简单的解决方案,但我似乎找不到它 - 请帮助 Stack Overflow!

标签: rfunctionlapply

解决方案


如果您使用的是 lapply,那么您只是在传递没有名称的数据框。也许如果你稍微改变一下方法:

set.seed(123)
x_data <- data.frame(A = rnorm(20),
                     B = rnorm(20))
y_data <- data.frame(A = rnorm(20),
                     B = rnorm(20))

add_x_or_y <- function(df, df_name) {
  df$x_or_y <- ifelse(grepl("x", df_name) == TRUE, "x", "y")
  df
}

x_y_list <- list(x_data = x_data,
                 y_data = y_data)

x_y_list <- mapply(add_x_or_y, 
                   x_y_list, 
                   names(x_y_list), SIMPLIFY = FALSE)

head(x_y_list$x_data, 3)
head(x_y_list$y_data, 3)

推荐阅读