我正在使用R中的两个数据帧,我正在尝试在将每个变量与数据帧进行比较后构建新变量,以便带来特定值。我的数据框是DF
和key
,它们看起来像这些(我在最后部分添加了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
此数据框有两个变量Name
和Value
。因此,我想将DF
(V1,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行代码。 DF
版dput()
和DF
是下一个:
key
答案 0 :(得分:1)
您可以将此作为" reshape-merge-reshape-merge"问题,虽然可能有一个更简单的方法。
如果您将DF
转换为长格式,则可以将Name
与key
合并,以便在一个数据集中获取所有值。然后,您可以从数据集中删除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