【问题标题】:R apply a vector of functions to a dataframeR将函数向量应用于数据框
【发布时间】:2020-04-02 16:00:01
【问题描述】:

我目前正在使用 cols 中的原始数字数据处理数据框。每列包含一个参数的数据(例如基因 xyz 的基因表达数据),而每一行包含一个主题。 cols 中的一些数据是正态分布的,而有些则远非正态分布。我使用 apply with margin 2 对不同的转换运行 shapiro 测试,然后通过比较 shapiro.test()$p.value 选择合适的转换。我将我的选择作为 char 发送到一个向量,给了我一个长度为 ncol(DataFrame) 的 NA、log10、sqrt 向量。我现在想知道是否可以通过应用函数将向量应用于数据帧,或者是否需要一个 for 循环。我该怎么做或有更好的方法?我想我可以循环 if-else 语句,但必须有更有效的方法,因为我的代码已经很慢了。

谢谢大家!

更新:我尝试了下面的代码,但它给了我“文件错误(文件名,“r”):无效的“描述”参数”

TransformedExampleDF <- apply(exampleDF, 2 , function(x) eval(parse(paste(transformationVector , "(" , x , ")" , sep = "" ))))

exampleDF <- as.data.frame(matrix(c(1,2,3,4,1,10,100,1000,0.1,0.2,0.3,0.4), ncol=3, nrow = 4))

transformationVector <- c(NA, "log10", NA)

【问题讨论】:

  • 所以你想对每一列的数据应用不同的转换,参数来自你提到的向量?
  • 正是。我有 3 种不同的“转换”。无(目前为 NA,但可以轻松更改)、log10 和 sqrt。该向量仅包含这 3 个不同的元素,其顺序是通过 apply 拟合 col-wise shapiro.tests 的结果。

标签: r


【解决方案1】:

所以你可以做这样的事情。在下面的示例中,我创建了四个随机函数,然后将它们的名称存储在列表 func_list 中(注意:最后一个函数将数据转换为 NA;这是有意的) .

然后,我创建了另一个函数 func_to_df(),它接受 data.frame 和函数列表 (func_list) 作为输入,并在data.frame。返回输出(在本例中,存储在data.framemy_df1

tl;dr: 看看func_to_df() 做了什么。可能也值得研究一下purrr 包(尽管这里没有使用它)。

#---------------------

#Example function 1
myaddtwo <- function(x){
  if(is.numeric(x)){
    x = x+2
  } else{
    warning("Input must be numeric!")
  }
  return(x)
  #Constraints such as the one shown above
  #can be added elsewhere to prevent
  #inappropriate action
}

#Example function 2
mymulttwo <- function(x){
  return(x*2)
}

#Example function 3
mysqrt <- function(x){
  return(sqrt(x))
}

#Example function 4
myna <- function(x){
  return(NA)
}

#---------------------

#Dummy data
my_df <- data.frame(
  matrix(sample(1:100, 40, replace = TRUE), 
         nrow = 10, ncol = 4), 
  stringsAsFactors = FALSE)

#User somehow ascertains that
#the following order of functions
#is the right one to be applied to the data.frame
my_func_list <- c("myaddtwo", "mymulttwo", "mysqrt", "myna")

#---------------------

#A function which applies
#the functions from func_list
#to the columns of df
func_to_df <- function(df, func_list){
  for(i in 1:length(func_list)){
    df[, i] <- get(func_list[i])(df[, i])
    #Alternative to get()
    #df[, i] <- eval(as.name(func_list[i]))(df[, i])
  }
  return(df)
}

#---------------------

#Execution

my_df1 <- func_to_df(my_df, my_func_list)

#---------------------

#Output
my_df
#    X1 X2 X3 X4
# 1   8 85  6 41
# 2  45  7  8 65
# 3  34 80 16 89
# 4  34 62  9 31
# 5  98 47 51 99
# 6  77 28 40 72
# 7  24  7 41 46
# 8  45 80 75 30
# 9  93 25 39 72
# 10 68 64 87 47

my_df1
#     X1  X2       X3 X4
# 1   10 170 2.449490 NA
# 2   47  14 2.828427 NA
# 3   36 160 4.000000 NA
# 4   36 124 3.000000 NA
# 5  100  94 7.141428 NA
# 6   79  56 6.324555 NA
# 7   26  14 6.403124 NA
# 8   47 160 8.660254 NA
# 9   95  50 6.244998 NA
# 10  70 128 9.327379 NA

#---------------------

【讨论】:

  • 感谢 Dunois,这不仅看起来像我需要它做的那样,而且对于像我这样的初学者来说也很有帮助。猜猜我接下来需要深入研究自定义函数。
  • @GrafZahl 不客气!用户定义的函数绝对是您前进道路上的一个有用的进站。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-18
  • 1970-01-01
  • 1970-01-01
  • 2013-03-30
  • 2015-04-23
  • 1970-01-01
相关资源
最近更新 更多