#r #dataframe #nlp #tidyr
#r #фрейм данных #нлп #тидир
Вопрос:
У меня есть большой файл df с платформы опроса. столбцы содержат один вопрос(в качестве заголовка) со всеми возможными ответами. Я пытаюсь разделить каждый из этих столбцов ответов на новый набор столбцов (с именем ответа в качестве имени нового столбца).
после этого я хотел бы, чтобы в каждом новом столбце указывалось, отображается ли значение в исходном столбце(с «1»), чтобы упростить обработку данных
dflt;-data.frame("name"= c("John","mark","bell","elsa"),"what do you like to eat"=c("apple","fries apple","peach","bread"))
оригинальный df
Имя | Что.тебе.нравится.есть? |
---|---|
Джон | Apple |
Марк | жареное яблоко |
колокол | персик |
эльза | хлеб |
я использую этот код, который работает, но я уверен, что должен быть более эффективный/простой способ сделать это, так как у меня более 50 столбцов, подобных этому.
dflt;-df %gt;% separate(what.do.you.like.to.eat, c("apple","fries","peach","bread",NA ), remove = F) df[,3:6]lt;-"" { df[,3] = with(df, ifelse(grepl("apple", df$what.do.you.like.to.eat,ignore.case = T), paste('1', df[,3]), paste("", df[,3]))) df[,4] = with(df, ifelse(grepl("fries", df$what.do.you.like.to.eat,ignore.case = T), paste('1', df[,4]), paste("", df[,4]))) df[,5] = with(df, ifelse(grepl("peach", df$what.do.you.like.to.eat,ignore.case = T), paste('1', df[,5]), paste("", df[,5]))) df[,6] = with(df, ifelse(grepl("bread", df$what.do.you.like.to.eat,ignore.case = T), paste('1', df[,6]), paste("", df[,6]))) }
желаемый результат
Имя | Что.тебе.нравится.есть? | Apple | картофель фри | персик | хлеб |
---|---|---|---|---|---|
Джон | Apple | 1 | |||
Марк | жареное яблоко | 1 | 1 | ||
колокол | персик | 1 | |||
эльза | хлеб | 1 |
Комментарии:
1. Честно говоря, я изо всех сил пытаюсь понять, что это довольно расплывчато, поэтому не могли бы вы предоставить образец ваших данных и образец ожидаемого результата ?
2. только что сделал, отправил по ошибке без примера
Ответ №1:
Вы можете использовать purrr::map
, чтобы применить свой вектор ответов и для каждого из них проверить их наличие в строке.
library(tidyverse) df lt;- data.frame( name = c("John", "mark", "bell", "elsa"), "what do you like to eat" = c("apple", "fries apple", "peach", "bread") ) ans lt;- c("apple", "fries", "peach", "bread") map_dfc(ans,~ transmute(df, !!sym(.x) := str_detect(what.do.you.like.to.eat, .x))) %gt;% bind_cols(df, .) #gt; name what.do.you.like.to.eat apple fries peach bread #gt; 1 John apple TRUE FALSE FALSE FALSE #gt; 2 mark fries apple TRUE TRUE FALSE FALSE #gt; 3 bell peach FALSE FALSE TRUE FALSE #gt; 4 elsa bread FALSE FALSE FALSE TRUE
Комментарии:
1. спасибо, это отлично работает, в том числе и со строками. есть ли возможность привязать столбец результатов с помощью функции bind_cols в определенном месте во фрейме данных.? (аналогично : dplyr::переместить(ans, .after = имя)
Ответ №2:
Хорошо, я сделал это, скажи мне, работает ли это для тебя :
my_df lt;- data.frame("name" = c("John","mark","bell","elsa"), "what do you like to eat" = c("apple","fries apple","peach","bread"), stringsAsFactors = FALSE) my_var lt;- unique(sort(str_split(string = my_df$what.do.you.like.to.eat, pattern = " ", simplify = TRUE))) my_pos lt;- which(my_var == "") if (length(my_pos)) { my_var lt;- my_var[-my_pos] } my_col lt;- c(colnames(my_df), my_var) my_miss lt;- setdiff(my_col, colnames(my_df)) my_df[my_miss] lt;- NA my_f lt;- function(x, y) { my_var lt;- grep(pattern = colnames(my_df)[x], x = my_df[, y]) if (length(my_var)) { my_df[my_var, x] lt;lt;- 1 } } lapply(3:ncol(my_df), function(x) my_f(x, 2))
вы можете изменить эту часть на эту :
my_df lt;- data.frame("name" = c("John","mark","bell","elsa"), "what do you like to eat" = c("i like apple","i love fries apple","i'm kind of peach","bread all the way"), stringsAsFactors = FALSE) my_var lt;- unique(sort(str_split(string = my_df$what.do.you.like.to.eat, pattern = " ", simplify = TRUE))) my_food lt;- c("apple", "fries", "bread", "peach") my_var lt;- my_var[which(my_var %in% my_food)] my_pos lt;- which(my_var == "") if (length(my_pos)) { my_var lt;- my_var[-my_pos] }
Комментарии:
1. это отлично работает с этим примером, так что спасибо. проблема в том, что в исходном df ответ в основном состоит из отдельных строк, таких как «я люблю есть яблоки»;» я очень люблю хлеб»; и т.д. есть ли способ определить my_var, чтобы он мог обнаружить такую строку, или ее нужно добавить вручную в эту переменную?