【问题标题】:dplyr mutate - How do I pass one row as a function argument?dplyr mutate - 如何将一行作为函数参数传递?
【发布时间】:2018-04-01 16:40:26
【问题描述】:

我正在尝试在我的 tibble 中创建一个新列,用于收集和格式化在所有其他列中找到的所有单词。如果可能的话,我想使用 dplyr 来做到这一点。 原始数据框:

df <- read.table(text =      "  columnA     columnB      
                 1            A           Z                    
                 2            B           Y                    
                 3            C           X                    
                 4            D           W                    
                 5            E           V                   
                 6            F           U            "  ) 

作为一个简化的例子,我希望做这样的事情:

df %>%
    rowwise() %>%
    mutate(newColumn = myFunc(.))

让输出看起来像这样:

       columnA     columnB      newColumn
1            A           Z             AZ        
2            B           Y             BY        
3            C           X             CX        
4            D           W             DW        
5            E           V             EV        
6            F           U             FU       

当我在我的代码中尝试这个时,输出看起来像:

       columnA     columnB      newColumn
1            A           Z             ABCDEF        
2            B           Y             ABCDEF        
3            C           X             ABCDEF    
4            D           W             ABCDEF    
5            E           V             ABCDEF    
6            F           U             ABCDEF

myFunc 应该将一行作为参数,但是当我尝试使用 rowwise() 时,我似乎将整个 tibble 传递到函数中(我可以通过将打印函数添加到 myFunc 中看到这一点)。

如何只传递一行并迭代地执行此操作,以便将函数应用于每一行?这可以用 dplyr 完成吗?

编辑:

为了我的问题,示例中的

myFunc 进行了简化。实际函数如下所示:

get_chr_vector <- function(row) {

    row <- row[,2:ncol(row)] # I need to skip the first row
    words <- str_c(row, collapse = ' ')
    words <- str_to_upper(words)
    words <- unlist(str_split(words, ' '))
    words <- words[words != '']
    words <- words[!nchar(words) <= 2]
    words <- removeWords(words, stopwords_list) # from the tm library
    words <- paste(words, sep = ' ', collapse = ' ')
}

【问题讨论】:

  • 你能分享myFunc吗? df 长什么样子?
  • 也许我理解错了,df %&gt;% mutate(newColumn=paste0(columnA, columnB)) 没有提供你想要的结果吗?
  • 为了我的问题,我简化了我的功能。我正在使用的实际功能已编辑到我的帖子中。
  • @BryanStafford 是否必须使用自己的函数?
  • @DataTx 不一定。我希望用我自己的来保持整洁。

标签: r dplyr rowwise


【解决方案1】:

看看?dplyr::do?purrr::map,它们允许您将任意函数应用于任意列并通过多个一元运算符链接结果。例如,

df1 <- df %>% rowwise %>% do( X = as_data_frame(.) ) %>% ungroup
# # A tibble: 6 x 1
#                  X
# *           <list>
# 1 <tibble [1 x 2]>
# 2 <tibble [1 x 2]>
# ...

请注意,X 列现在包含 1x2 data.frames(或 tibbles),由原始 data.frame 中的行组成。您现在可以使用 map 将每一个传递给您的自定义 myFunc

myFunc <- function(Y) {paste0( Y$columnA, Y$columnB )}
df1 %>% mutate( Result = map(X, myFunc) )
# # A tibble: 6 x 2
#                  X    Result
#             <list>    <list>
# 1 <tibble [1 x 2]> <chr [1]>
# 2 <tibble [1 x 2]> <chr [1]>
# ...

Result 列现在包含myFunc 的输出,根据需要应用于原始data.frame 中的每一行。您可以通过连接 tidyr::unnest 操作来检索这些值。

df1 %>% mutate( Result = map(X, myFunc) ) %>% unnest
# # A tibble: 6 x 3
#   Result columnA columnB
#    <chr>  <fctr>  <fctr>
# 1     AZ       A       Z
# 2     BY       B       Y
# 3     CX       C       X
# ...

如果需要,unnest 可以限制为特定列,例如 unnest(Result)

编辑:因为您原来的data.frame 仅包含两列,您实际上可以跳过do 步骤并改用purrr::map2。语法非常类似于map:

myFunc <- function( a, b ) {paste0(a,b)}
df %>% mutate( Result = map2( columnA, columnB, myFunc ) )

请注意,myFunc 现在定义为二进制函数。

【讨论】:

    【解决方案2】:

    这应该可以工作

       df <- read.table(text =      "  columnA     columnB      
                     1            A           Z                    
                     2            B           Y                    
                     3            C           X                    
                     4            D           W                    
                     5            E           V                   
                     6            F           U            "  )  
    
    df %>%
      mutate(mutate_Func = paste0(columnA,columnB))
    
       columnA columnB mutate_Func
    1       A       Z          AZ
    2       B       Y          BY
    3       C       X          CX
    4       D       W          DW
    5       E       V          EV
    6       F       U          FU
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-23
      • 1970-01-01
      • 2015-03-29
      • 2015-03-14
      • 1970-01-01
      • 2018-05-09
      相关资源
      最近更新 更多