【问题标题】:apply function to every element in data.frame and return data.frame将函数应用于 data.frame 中的每个元素并返回 data.frame
【发布时间】:2018-07-17 15:37:53
【问题描述】:

更新:之前,我使用paste 函数作为示例,而不是任意的myFun 函数。这个问题稍微容易一些,因为paste 实际上可以对向量进行操作,而myFun 则不能。

我想将我自己的函数元素应用于 data.frame 中的每个元素,并将修改后的 data.frame 作为返回值。

例子:

> df <- data.frame(c(1,2,3), c(2,3,4))
> df
  c.1..2..3. c.2..3..4.
1          1          2
2          2          3
3          3          4
> df_x <- magical_apply_function(df, function(x) myFun
> df_x
  c.1..2..3. c.2..3..4.
1         myFun(1)         myFun(2)
2         myFun(2)         myFun(3)
3         myFun(3)         myFun(4)

对于无法在互联网上的任何地方找到此问题的答案,我感到非常困惑。大多数资源都在谈论 applylapplysapply,但这些资源仅适用于向量/列表,并且仅返回列表。

for 循环真的是唯一的方法吗?

【问题讨论】:

  • 只需使用lapply,q.v。下面的@akrun 答案。
  • 尽管有以下解决方案,但我很困惑为什么你会感到困惑。收集不同数据是 data.frames 存在的理由。虽然如果您可以将函数应用于整个 DF,则粘贴在这里有效,但通常它应该是一个矩阵。
  • 奖励:要应用的函数不能处理向量

标签: r dataframe element apply


【解决方案1】:

我们可以使用mutate_alldplyr

library(dplyr)
df %>% 
     mutate_all(funs(paste0(., "x")))

或者用lapplybase R转换成data.frame

data.frame(lapply(df, paste0,  "x"))

【讨论】:

    【解决方案2】:
    df <- data.frame(c(1,2,3), c(2,3,4))
    df[] <- lapply(df, function(x) paste(x,"x", sep=""))
    df
    

    df[] 保留数据框的结构。

    【讨论】:

    • 当我做与此类似的事情时(相同的原理,不同的函数(x))我收到一个错误,指出参数意味着不同的行数:3877、3890、3884、3925、4024、3942, 2758, 4042, 4796, 7297 我在 myFun 中使用 unlist() 函数,我认为它搞砸了长度,因为它在列表列表上运行。
    • 天哪,确实,unlist() 函数取消列出的不仅仅是一级列表。
    • 第二个问题的解决方案是使用 unlist() 和选项 recursive=F 然后一切正常。
    【解决方案3】:

    另请参阅这些 purrr 函数

    library(purrr)
    modify(df,paste0,"x") # output is of the same type input, so `data.frame` here
    
    #   c.1..2..3. c.2..3..4.
    # 1         1x         2x
    # 2         2x         3x
    # 3         3x         4x
    
    map_df(df,paste0,"x") # output is always tibble
    
    # # A tibble: 3 x 2
    #   c.1..2..3. c.2..3..4.
    #        <chr>      <chr>
    # 1         1x         2x
    # 2         2x         3x
    # 3         3x         4x
    

    【讨论】:

      【解决方案4】:

      你不能用apply(df, c(1,2), myFun)吗?使用c(1,2) 将分别将该函数应用于数据框中的每个项目:

      MARGIN 一个向量,给出函数将被应用的下标。例如,对于矩阵,1 表示行,2 表示列,c(1, 2) 表示行和列。

      > temp<-data.frame(le=LETTERS[1:3], nu=20:22)
      > temp
        le nu
      1  A 20
      2  B 21
      3  C 22
      > apply(temp, c(1,2), function(x) {gsub('d',x,'d1d1')})
           le     nu      
      [1,] "A1A1" "201201"
      [2,] "B1B1" "211211"
      [3,] "C1C1" "221221"
      

      如果按行应用函数,则函数使用不正确:

      > apply(temp, 1, function(x) {gsub('d',x,'d1d1')})
      [1] "A1A1" "B1B1" "C1C1"
      Warning messages:
      1: In gsub("d", x, "d1d1") :
        argument 'replacement' has length > 1 and only the first element will be used
      2: In gsub("d", x, "d1d1") :
        argument 'replacement' has length > 1 and only the first element will be used
      3: In gsub("d", x, "d1d1") :
        argument 'replacement' has length > 1 and only the first element will be used
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-28
        • 1970-01-01
        • 2015-01-18
        • 2015-07-12
        • 2019-07-16
        • 2019-05-09
        • 1970-01-01
        • 2015-02-23
        相关资源
        最近更新 更多