我正在尝试在我的 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 " )
Run Code Online (Sandbox Code Playgroud)
作为一个简化的例子,我希望做类似的事情:
df %>%
rowwise() %>%
mutate(newColumn = myFunc(.))
Run Code Online (Sandbox Code Playgroud)
输出如下所示:
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
Run Code Online (Sandbox Code Playgroud)
当我在代码中尝试此操作时,输出如下所示:
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
Run Code Online (Sandbox Code Playgroud)
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 = ' ')
}
Run Code Online (Sandbox Code Playgroud)
看一下?dplyr::doand ?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]>
# ...
Run Code Online (Sandbox Code Playgroud)
请注意,列X现在包含 1x2 data.frames(或tibbles),由原始data.frame. myFunc您现在可以使用将每一项传递给您的自定义map。
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]>
# ...
Run Code Online (Sandbox Code Playgroud)
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
# ...
Run Code Online (Sandbox Code Playgroud)
如果需要,unnest可以限制为特定列,例如unnest(Result)。
编辑:因为您的原始文件data.frame仅包含两列,所以您实际上可以跳过该do步骤并使用purrr::map2。语法非常类似于map:
myFunc <- function( a, b ) {paste0(a,b)}
df %>% mutate( Result = map2( columnA, columnB, myFunc ) )
Run Code Online (Sandbox Code Playgroud)
请注意,myFunc现在定义为二元函数。