在逐个比较另一个数据帧并使用特定名称后,在R中的数据框中创建变量

时间:2014-10-11 18:54:11

标签: r dplyr

我正在使用R中的两个数据帧,我正在尝试在将每个变量与数据帧进行比较后构建新变量,以便带来特定值。我的数据框是DFkey,它们看起来像这些(我在最后部分添加了dput版本):

DF

   ID V1    V2     V3 V4 V5
1 001  Y Zone1 Level0 M1  T
2 002  N Zone2 Level1 M2  O
3 003  N Zone3 Level0 M3 NR
4 004  Y    NR Level0 M4  O
5 005 NR    NR Level0 M4  O
6 006  Y    NR Level1 M4  T
7 007  Y Zone3 Level1 M1  T
8 008  N Zone2 Level1 M1  T
9 009 NR Zone2 Level0 M1  T 

DF有ID变量和五个变量。另一个key具有下一种形式:

key
     Name Value
1       Y    15
2       N    20
3   Zone1    34
4   Zone2     1
5   Zone3     2
6  Level0     9
7  Level1     8
8      M1     4
9      M2     5
10     M3     6
11     M4     8
12     M5     9
13      T     2
14      O     5

此数据框有两个变量NameValue。因此,我想将DFV1,V2,V3,V4,V5)中的每个变量与Name中的key变量进行比较,以创建保存{{1}值的新变量经过他们各自的比较。新变量必须具有下一个名称结构:Value,因此我构建了此代码:

VI_Name.of.variable.in.DF_M

使用这些行,我将DF$VI_V1_M=key[match(DF$V1,key$Name),"Value"] DF$VI_V2_M=key[match(DF$V2,key$Name),"Value"] DF$VI_V3_M=key[match(DF$V3,key$Name),"Value"] DF$VI_V4_M=key[match(DF$V4,key$Name),"Value"] DF$VI_V5_M=key[match(DF$V5,key$Name),"Value"] 中的每个变量与DF中的Name进行比较以带来key,但我不知道如何创建for结构或一个带有apply的函数,用于构建所需的变量,因为Value中的变量数量可以增加。我想得到这样的东西:

DF

比较每个变量的结果保存在新变量中。我正在寻找一种减少行数的解决方案,因为 ID V1 V2 V3 V4 V5 VI_V1_M VI_V2_M VI_V3_M VI_V4_M VI_V5_M 1 001 Y Zone1 Level0 M1 T 15 34 9 4 2 2 002 N Zone2 Level1 M2 O 20 1 8 5 5 3 003 N Zone3 Level0 M3 NR 20 2 9 6 NA 4 004 Y NR Level0 M4 O 15 NA 9 8 5 5 005 NR NR Level0 M4 O NA NA 9 8 5 6 006 Y NR Level1 M4 T 15 NA 8 8 2 7 007 Y Zone3 Level1 M1 T 15 2 8 4 2 8 008 N Zone2 Level1 M1 T 20 1 8 4 2 9 009 NR Zone2 Level0 M1 T NA 1 9 4 2 中有100个变量,我需要编写100行代码。 DFdput()DF是下一个:

key

1 个答案:

答案 0 :(得分:1)

您可以将此作为" reshape-merge-reshape-merge"问题,虽然可能有一个更简单的方法。

如果您将DF转换为长格式,则可以将Namekey合并,以便在一个数据集中获取所有值。然后,您可以从数据集中删除Name变量,更改值V1 - V5(现在位于列中)以匹配您的命名结构,然后将数据集重新整形为宽将前一列Value格式化为列值。再与原始DF合并,使其成为您想要的最终格式。似乎有一种方法可以用较少的步骤来做这些事情,但我还没有想到任何事情。

我使用包 tidyr 进行重新整理,使用 dplyr 进行操作。

library(tidyr)
library(dplyr)

DF %>%
    gather(Variable, Name, V1:V5) %>% # Put DF in long format
    inner_join(key, by = "Name") %>% # Join with "key" dataset
    select(-Name) %>% # Remove "Name" now so doesn't interfere with spread()
    mutate(Variable = paste("VI", Variable, "M", sep = "_")) %>% # Make names for columns
    spread(Variable, Value) %>% # Put dataset back into wide format
    inner_join(DF, ., by = "ID") # Join with original DF

   ID V1    V2     V3 V4 V5 VI_V1_M VI_V2_M VI_V3_M VI_V4_M VI_V5_M
1 001  Y Zone1 Level0 M1  T      15      34       9       4       2
2 002  N Zone2 Level1 M2  O      20       1       8       5       5
3 003  N Zone3 Level0 M3 NR      20       2       9       6      NA
4 004  Y    NR Level0 M4  O      15      NA       9       8       5
5 005 NR    NR Level0 M4  O      NA      NA       9       8       5
6 006  Y    NR Level1 M4  T      15      NA       8       8       2
7 007  Y Zone3 Level1 M1  T      15       2       8       4       2
8 008  N Zone2 Level1 M1  T      20       1       8       4       2
9 009 NR Zone2 Level0 M1  T      NA       1       9       4       2