dplyr mutate - как передать одну строку в качестве аргумента функции?
Я пытаюсь создать новый столбец в моей таблице, который собирает и форматирует все слова, найденные во всех других столбцах. Я хотел бы сделать это с помощью dplyr, если это возможно. Исходный DataFrame:
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(), мне кажется, что я передаю всю функцию в функцию (я вижу это, добавив функцию печати в 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 = ' ')
}
2 ответа
Взгляни на ?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.frame
с (или tibble
s) состоит из строк из вашего оригинала 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]>
# ...
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
теперь определяется как двоичная функция.
Это должно работать
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