R, Dplyr, объединить информацию по группам и спецификациям строк / столбцов - PullRequest
0 голосов
/ 13 ноября 2018

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

df <- data_frame(person = c(rep("Joe",4),rep("Bob",3)),
               meal = c(seq(1:4),seq(1:3)),
               food = c("Chicken", "Beef", "Soup and meal 2", "Lamb",
                        "Lamb","Salad and meal 1","Beef"),
               dependencies = c(NA,NA,2,3,NA,1,NA),
               solo_meal = c(1,1,0,1,1,0,1))

Я хочу создать новый столбец, который будет выглядеть так:

data_frame(combined_meal = c("Chicken", "Beef", "Soup and Beef", "Lamb",
                              "Lamb","Salad and Lamb","Beef"))

Если используется зависимость, я хочу объединить эту «еду» с «едой».

У меня большой набор данных с несколькими зависимостями, которые мне нужно объединить в одно поле. Я чувствую, что должен быть простой способ сделать это, но я не могу придумать один.

Спасибо!

редактировать: Я хочу поблагодарить тех, кто прокомментировал до сих пор. Опция Tidyverse работала лучше всего для моих нужд. У меня есть одна правка, которую я хотел добавить - при поиске в еде - мне может понадобиться добавить более одной еды вместе.

df <- data_frame(person = c(rep("Joe",4),rep("Bob",3)),
               meal = c(seq(1:4),seq(1:3)),
               food = c("Chicken", "Beef", "Soup and meal 2", "Lamb and meal 3",
                        "Lamb","Salad and meal 1","Beef"),
               dependencies = c(NA,NA,2,3,NA,1,NA),
               solo_meal = c(1,1,0,1,1,0,1))

, что дает:

# A tibble: 7 x 5


  person  meal food             dependencies solo_meal
  <chr>  <int> <chr>                   <dbl>     <dbl>
1 Joe        1 Chicken                    NA         1
2 Joe        2 Beef                       NA         1
3 Joe        3 Soup and meal 2             2         0
4 Joe        4 Lamb and meal 3             3         1
5 Bob        1 Lamb                       NA         1
6 Bob        2 Salad and meal 1            1         0
7 Bob        3 Beef                       NA         1

Я хочу иметь колонку комбинированных блюд:

# A tibble: 7 x 1
  combined_meal         
  <chr>                 
1 Chicken               
2 Beef                  
3 Soup and Beef         
4 Lamb and Soup and Beef
5 Lamb                  
6 Salad and Lamb        
7 Beef  

Как мне рекурсивно добавить блюда? Предпочтительно использовать тидиверс.

Еще раз спасибо!

Ответы [ 3 ]

0 голосов
/ 13 ноября 2018

Решение с использованием tidyverse. Идея состоит в том, чтобы самостоятельно присоединиться к таблице df на основе person, dependencies и mean, а затем выполнить некоторые дальнейшие операции.

library(tidyverse)

df2 <- df %>%
  left_join(df %>% select(-dependencies, -solo_meal), 
            by = c("person", "dependencies" = "meal")) %>%
  mutate(food.z = str_replace(food.x, "meal [0-9]", "")) %>%
  mutate(combined_meal = ifelse(is.na(food.y), food.z, str_c(food.z, food.y, sep = ""))) %>%
  rename(food = food.x) %>%
  select(names(df), combined_meal)
df2
# # A tibble: 7 x 6
#   person  meal food             dependencies solo_meal combined_meal 
#   <chr>  <int> <chr>                   <dbl>     <dbl> <chr>         
# 1 Joe        1 Chicken                    NA         1 Chicken       
# 2 Joe        2 Beef                       NA         1 Beef          
# 3 Joe        3 Soup and meal 2             2         0 Soup and Beef 
# 4 Joe        4 Lamb                       NA         1 Lamb          
# 5 Bob        1 Lamb                       NA         1 Lamb          
# 6 Bob        2 Salad and meal 1            1         0 Salad and Lamb
# 7 Bob        3 Beef                       NA         1 Beef  
0 голосов
/ 13 ноября 2018

Решение для одной строки (с использованием dplyr):

df %>% group_by(person) %>% 
mutate(combined_meal=ifelse(!is.na(dependencies), paste0(gsub("(.* and ).*","\\1",food), food[dependencies]),food))

Для каждого person мы создаем столбец combined_meal, где, если нет dependencies, он повторяет все, что находится в food и, если он есть, он paste объединяет все, что стоит перед словом "и", с тем, что находится в столбце пищи с номером строки зависимости.

(Обратите внимание, что предполагается, что число в «зависимости» совпадает с номером строки фрейма данных, если мы получаем фрейм данных только для этого человека. Это также означает, что фрейм данных отсортирован по mealЕсли это предположение неверно, вы можете включить строку arrange(meal) после group_by.)

Результат:

# A tibble: 7 x 6
# Groups:   person [2]
  person  meal food             dependencies solo_meal combined_meal 
  <chr>  <int> <chr>                   <dbl>     <dbl> <chr>         
1 Joe        1 Chicken                   NA         1. Chicken       
2 Joe        2 Beef                      NA         1. Beef          
3 Joe        3 Soup and meal 2            2.        0. Soup and Beef 
4 Joe        4 Lamb                      NA         1. Lamb          
5 Bob        1 Lamb                      NA         1. Lamb          
6 Bob        2 Salad and meal 1           1.        0. Salad and Lamb
7 Bob        3 Beef                      NA         1. Beef         
0 голосов
/ 13 ноября 2018

Это базовое решение.(Я считаю, что базовые решения легче понять.) Вы делаете индексный вектор строк для изменения, а затем строите новое значение из элементов, которые должны быть изменены, и элементов, непосредственно предшествующих им (что в вашем примере представляется назначенной задачей.

 idx <- which(grepl("meal", df$food))
 df[ idx, "combined_meal"] <- 
             paste( sub("meal.*$", "", df$food[idx] ), df$food [idx-1] )

 # The fill in NA's with the original `food` values
 df$combined_meal[ is.na(df$combined_meal)] <-
          df$food[ is.na(df$combined_meal)]



> df
# A tibble: 7 x 6
  person  meal food             dependencies solo_meal combined_meal  
  <chr>  <int> <chr>                   <dbl>     <dbl> <chr>          
1 Joe        1 Chicken                    NA         1 Chicken        
2 Joe        2 Beef                       NA         1 Beef           
3 Joe        3 Soup and meal 2             2         0 Soup and  Beef 
4 Joe        4 Lamb                       NA         1 Lamb           
5 Bob        1 Lamb                       NA         1 Lamb           
6 Bob        2 Salad and meal 1            1         0 Salad and  Lamb
7 Bob        3 Beef                       NA         1 Beef           
> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...