Изменение элементов тибла внутри функции - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть набор строковых переменных в моей таблице, которые я хочу перекодировать в конкретные целые числа в зависимости от содержимого их строк.Мой код выглядит следующим образом:

library(tidyverse)

a<-c("this string says apple", "this string says banana", "this string says carrot", "this string says apple")
b<- c("this string says pumpkin", "this string says radish", "this string says eggplant", "this string says radish")
produce <- tibble(a,b)

a_words <- c("apple", "banana", "carrot")
b_words <- c("pumpkin", "radish", "eggplant")

my_function<-function(var,word_vec,num_vec){ 
  for (i in seq_along(word_vec)){
    var[grepl(word_vec[[i]],var)]<-num_vec[[i]]
  }
  return(var)
}

Я могу получить желаемый результат, когда обрабатываю каждую переменную отдельно:

produce$a <- my_function(produce$a,a_words,1:3)
produce$b <- my_function(produce$b,b_words,1:3)

> produce
# A tibble: 4 x 2
  a     b    
  <chr> <chr>
1 1     1    
2 2     2    
3 3     3    
4 1     2  

Но на самом деле у меня есть несколько переменных для перекодирования (ноне все переменные в тибле).Я попробовал функцию цикла:

for (i in c("produce$a", "produce$b")){
  i <- my_function(i, paste0(str_replace(i,"produce$", ""),"_words"), 1:3)
}

Но это не меняет тиббл продукта.

Буду признателен за любые предложения о том, как сделать это более эффективно.

Ответы [ 2 ]

0 голосов
/ 06 декабря 2018

Вы проделали хорошую работу, но сделали несколько путаниц.

Прежде всего, вы сделали одну, касающуюся разницы между строками и переменными: «производить $ a» - это не то же самое, что производить.$ а.Функция get() - это то, что вам нужно, чтобы получить второе из первого.

Кроме того, функция paste0() выполняет некоторую оценку некоторых символов строки, которую вы передаете в качестве аргумента.«$» - один из них.

Чтобы закончить, вы должны научиться использовать другой метод доступа к столбцам вашего фрейма данных, отличный от df $ X , например df[["X"]] или df ["X"] .У них свой собственный способ поведения, вы должны узнать об этом.

В любом случае, ниже приведен код, который - я думаю - вы искали.

for (i in c("a", "b")){
  print(my_function(produce[[i]], get(paste0(i,"_words")), 1:3))
}

NB:Я изменил список цикла на c («a», «b»), потому что это легче понять, но вы могли бы также зациклить c("produce$a", "produce$b") и получить решение с несколькими изменениями.

0 голосов
/ 06 декабря 2018

Примерно так:

words <- list(
    a = c("apple", "banana", "carrot"),
    b = c("pumpkin", "radish", "eggplant"))

produce %>%
    rowid_to_column("row") %>%
    gather(key, val, -row) %>%
    rowwise() %>%
    mutate(val = map_int(words[key], ~which(str_detect(val, .x) == TRUE))) %>%
    spread(key, val) %>%
    select(-row)
## A tibble: 4 x 2
#      a     b
#  <int> <int>
#1     1     1
#2     2     2
#3     3     3
#4     1     2

Здесь ключ

  • хранить words в list с именами, совпадающими с именами столбцов в produce,
  • преобразование produce из широкого в длинный и
  • регулярное выражение-сопоставление записей из столбцов с именами в key с соответствующими записями из words перед повторным формированием данных обратноот длинного к широкому.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...