【问题标题】:R, Dplyr, Combine info by group and row/column specificationR,Dplyr,按组和行/列规范组合信息
【发布时间】:2018-11-13 00:49:54
【问题描述】:

我想创建一个包含两列信息的新列,但其中一列位于不同的行上。下面是我想开始的示例数据框:

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  

如何递归添加餐点?最好使用 tidyverse。

再次感谢!

【问题讨论】:

  • 重新编辑,为什么没有依赖乔的饭4?
  • 我忘记在编辑中更新该列。现在应该修好了。

标签: r dplyr


【解决方案1】:

这是一个基本解决方案。 (我发现基本解决方案更容易理解。)您制作要修改的行的索引向量,然后从要修改的项目和紧接在它们之前的项目构建一个新值(从您的示例来看,这似乎是分配的任务。

 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           
> 

【讨论】:

  • 这似乎是一个很大的假设,而不是 OP 对问题的描述的一部分。
  • 同意这是一种假设,但人们需要对预期的替代品做出某种假设,因为它们没有被描述。
  • 我认为很明显,替换是在“依赖项”下出现的数字,用于组合膳食(例如,对于乔来说,对第 3 行的依赖项是 2,即牛肉)。
  • 这显然对我来说并不明显。
  • 我喜欢基本示例的简单性,但我需要一次在多于 1 行之间移动。我也不确定它是否适合我给出的更新示例。
【解决方案2】:

使用tidyverse 的解决方案。想法是基于persondependenciesmean自加入df表,然后进行一些进一步的操作。

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  

【讨论】:

  • 这是迄今为止最好的答案,但我不确定如何使用我给出的更新示例来实现它。我想我需要第二轮加入,但这似乎比任何事情都更令人头疼。
  • @JoeShmo 我不知道如何解决您更新的问题。如果我的回答解决了你原来的问题,也许你可以接受我的回答,然后用你更新的问题发布一个新问题。通过这样做,更多人可能会看到您的问题并为您提供帮助。
【解决方案3】:

单线解决方案(使用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 中的任何内容,如果有,它将pastes 之前的所有内容放在一起单词“和”与食物列中的任何内容以及依赖项的行号。

(请注意,如果我们仅获取该人的数据框,则假设“依赖项”中的数字与数据框的行号相同。这也意味着数据框按meal 排序。如果那假设不正确,您可以在group_by 之后包含arrange(meal) 行。)

结果:

# 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         

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-05
    • 2017-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多