【问题标题】:Create a set of variables in a dataframe based on a set of rules from another data frame根据来自另一个数据帧的一组规则在一个数据帧中创建一组变量
【发布时间】:2020-02-10 17:53:07
【问题描述】:

这个问题听起来有点笼统,但我认为举个例子会更清楚:

我有以下两个数据框

数据1

group1     group2       group3     Level 
cat         cat          dog        1
dog         parrot       cat        1
mouse       dolphin      dolphin    1
red         blue         blue       2
green       yellow       green      2
black       purple       cat        2

数据2

var1        level    Score
cat           1        1
dog           1        1
mouse         1        1
dolphin       1        0
parrot        1        1
red           2        1
blue          2        1
green         2        1
purple        2        1
cat           2        0
black         2        0
yellow        2        1

我想修改包含 3 个新列(每个 group1、group2 和 group3 一个)的 data1,其值取决于我在 data2 的“score”列中找到的值,具体取决于“level”的级别(级别是一个因素)。所以基本上我想获得这样的东西:

group1     group2       group3     Level      var1     var2     var3
cat         cat          dog        1          1        1        1
dog         parrot       cat        1          1        1        1
mouse       dolphin      dolphin    1          1        0        0
red         blue         blue       2          1        1        1
green       yellow       green      2          1        1        1
black       purple       cat        2          0        1        0

样本数据

df1 <- structure(list(
  group1 = c("cat", "dog", "mouse", "red", "green", "black"),
  group2 = c("cat", "parrot", "dolphin", "blue", "yellow", "purple"),
  group3 = c("dog", "cat", "dolphin", "blue", "green", "cat"),
  Level = structure(c(1L, 1L, 1L, 2L, 2L, 2L), .Label = c("1", "2"), class = "factor")),
  row.names = c(NA, -6L), class = "data.frame")

df2 <- structure(list(
  var1 = c("cat", "dog", "mouse", "dolphin", "parrot", "red", "blue", "green", "purple", "cat", "black", "yellow"),
  level = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("1", "2"), class = "factor"),
  Score = c(1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 0L, 0L, 1L)),
  row.names = c(NA, -12L), class = "data.frame")

【问题讨论】:

  • @akrun:好点,我改了
  • @Darren Tsai:应该的,我无意中写的不一样
  • @Darren Tsai :另一个错误,我在 data2 中包含黄色:基本上数据 2 是从 data1 + 手动完成的变量 Score 创建的:输出显示返回表 1 格式匹配的意图每组的变量分数

标签: r


【解决方案1】:

我们可以将第一个数据集转为“长”格式,与第二个数据集连接,然后将其转回“宽”格式

library(dplyr)
library(tidyr)
library(stringr)
df1 %>%
    mutate(rn = row_number()) %>%
    pivot_longer(cols  = -c(rn, Level), values_to = 'var1') %>% 
    rename(level = Level) %>% 
    left_join(df2) %>% 
    mutate(name = str_replace(name, 'group', 'varn')) %>% 
    na.omit %>%
    select(-level, -var1) %>% 
    pivot_wider(names_from = name, values_from = Score, values_fill = list(Score = 0)) %>% 
    select(-rn) %>% 
    bind_cols(df1, .)
#   group1  group2  group3 Level varn1 varn2 varn3
#1    cat     cat     dog     1     1     1     1
#2    dog  parrot     cat     1     1     0     1
#3  mouse dolphin dolphin     1     1     0     0
#4    red    blue    blue     2     1     1     1
#5  green  yellow   green     2     1     0     1
#6  black  purple     cat     2     0     1     0

【讨论】:

    【解决方案2】:

    我通过purrr::reduce() 递归地将df2 合并到df1 三次。在这一部分中,我将df2 复制了三次,并将它们的第一列名称分别更改为与df1 中的名称匹配。

    library(tidyverse)
    
    df2 %>%
      list %>% rep(3) %>%
      imap(~ setNames(.x, c(str_c("group", .y), "Level", str_c("Score", .y)))) %>%
      reduce(left_join, .init = df1)
    
    #   group1  group2  group3 Level Score1 Score2 Score3
    # 1    cat     cat     dog     1      1      1      1
    # 2    dog  parrot     cat     1      1      1      1
    # 3  mouse dolphin dolphin     1      1      0      0
    # 4    red    blue    blue     2      1      1      1
    # 5  green  yellow   green     2      1      1      1
    # 6  black  purple     cat     2      0      1      0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-13
      • 2013-06-14
      • 1970-01-01
      • 2023-01-08
      • 1970-01-01
      • 1970-01-01
      • 2021-12-25
      • 2018-01-09
      相关资源
      最近更新 更多