【问题标题】:How to apply a specified function to multiple variables in a data frame?如何将指定函数应用于数据框中的多个变量?
【发布时间】:2019-07-10 11:04:22
【问题描述】:

我对编写函数很陌生,并且正在编写一个通用函数,该函数将应用于数据框中的多个(但不是全部)行。该函数应该有条件地转换这些指定行的值。

示例数据: df <- data.frame("Var1" = c(0:5), "Var2" = c(-5:0), "Var3" = c(0,0,0,0,0,0)

> df
  Var1 Var2 Var3
1    0   -5    0
2    1   -4    0
3    2   -3    0
4    3   -2    0
5    4   -1    0
6    5    0    0

示例函数:

myFun <- function(x, na_value){
  x[x == na_value] <- NA
  x
}

鉴于我希望 Var1 和 Var 2 的 0 转换为 NA - 但不是 Var3,我已经编写了 df$Var1 &lt;- myFun(df$Var1, 0)df$Var2 &lt;- myFun(df$Var2, 0) - 但是必须有一种更简单的方法吗?

我的设想类似于myFun(Var1, Var2, 0),它将 Var1 和 Var2 中的 0 转换为 NA,而无需为这两个变量重复代码。该函数将应用于具有不同变量名和不同 na_values 的多个数据帧,这就是我首先编写它的原因,它工作正常,但我想进一步简化。

【问题讨论】:

  • 另一种可能性:df[, c("Var1", "Var2")][df[, c("Var1", "Var2")] == 0] &lt;- NA

标签: r function


【解决方案1】:

对于单个数据帧,apply 是执行此操作的标准方法。例如这里:

df[ , -3] <- apply(df[ , -3], FUN = myFun, na_value = 0, MARGIN = 2)
df

但是,我不知道您的其他数据帧是否以完全相同的方式格式化。但是您可以结合 applylapply(或 mapply)对所有数据帧执行此操作。

编辑:这是一个更通用(而且有点难看或过时)的解决方案,带有for 循环:

## Define a list of two dataframes:
df <- data.frame("Var1" = c(0:5), "Var2" = c(-5:0), "Var3" = c(0,0,0,0,0,0))
df2 <- data.frame("VarA" = c(0:5), "VarB" = c(-5:0), "VarC" = c(3,3,3,3,3,3))
my_list <- list(df, df2)
## Colnames to consider, and missing values indicator, for each dataframe:
na_values <- list(0, 3) # NA = 0 in the first one, NA = 3 in the second
cols <- list(c("Var1", "Var2"), c("VarA", "VarB"))
## Define an R function to replace a given character by "NA" in a dataframe:
replace_nas <- function(data, cols, na_value){
    data[ , cols] <- lapply(data[ , cols], FUN = function(x) {
        x[x == na_value] <- NA
        return(x)
    }
    )
    return(data)
}
## Do this operation for each dataframe in "my_list" with a for loop:
res_list <- list()
for (k in 1:length(my_list)) {
    res_list[[k]] <- replace_nas(my_list[[k]], cols[[k]], na_values[[k]])
}
res_list

可能不是最佳的,但它有效!

【讨论】:

  • 恕我直言,最好将apply 用于arrays 和lapply 用于data.frames,因为第一个会将您的data.frame 强制转换为矩阵。
  • 哎呀,你是对的! :-) 这里所有的列都是数字,所以这并不重要,但在其他情况下这将是一个严重的问题。
  • 谢谢,lapply 非常适合这个简单的示例。有没有办法通过名称而不是df[ , -3]来识别我想应用函数的列?
  • 我编辑了我之前的答案以提出一个丑陋的解决方案!
【解决方案2】:

由于您要求更简单的解决方案,您可以只识别等于 0 的单元格,从而排除第 3 列,并将它们设置为 NA,如下所示:

df[-3][df[-3] == 0] <- NA
#   Var1 Var2 Var3
# 1   NA   -5    0
# 2    1   -4    0
# 3    2   -3    0
# 4    3   -2    0
# 5    4   -1    0
# 6    5   NA    0

【讨论】:

    猜你喜欢
    • 2020-09-04
    • 2013-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多