考虑保存在另一个数据帧中的行和列索引,从新变量中获取数据帧中的值

时间:2014-06-10 22:35:20

标签: r

大家好我想用R中的两个数据帧解决一个小问题。我的数据帧有下一个结构(我在最后一部分添加dput()版本)。第一个数据框是DF

   x1 x2 Index1 Index2
1 001  T      1      2
2 002  V      3      1
3 003  C      1      4
4 004  D      4      1
5 005  M      6      1
6 006  N      7      3

第二个数据框是DF2

   a1  a2 a3 a4
1 0.1 1.0 10  5
2 0.2 0.9  9  4
3 0.3 0.8  8  3
4 0.4 0.7  7  2
5 0.5 0.6  6  1
6 0.6 0.5  5  0
7 0.7 0.4  4  6

我正在努力解决这种情况。在DF我有两列Index1Index2。在这些列中,我想要在DF2中找到值并保存在DF的新变量中,例如DF中的第一行Index1一个值为1,而Index2的值为2,所以当我在DF2的括号中使用这些值时,我得到了这个:

DF2[1,2]
[1] 1
DF2[3,1]
[1] 0.3
DF2[1,4]
[1] 5
DF2[4,1]
[1] 0.4
DF2[6,1]
[1] 0.6
DF2[7,3]
[1] 4

这很好但是当我尝试创建一个新变量来获取这些值时,我使用了一个带括号的类似结构,所以我使用了:

DF$I3=DF2[DF$"Index1",DF$"Index2"]

但我得到了错误的结果:

   x1 x2 Index1 Index2 I3.a2 I3.a1 I3.a4 I3.a1.1 I3.a1.2 I3.a3
1 001  T      1      2   1.0   0.1     5     0.1     0.1    10
2 002  V      3      1   0.8   0.3     3     0.3     0.3     8
3 003  C      1      4   1.0   0.1     5     0.1     0.1    10
4 004  D      4      1   0.7   0.4     2     0.4     0.4     7
5 005  M      6      1   0.5   0.6     0     0.6     0.6     5
6 006  N      7      3   0.4   0.7     6     0.7     0.7     4

此外,我尝试使用apply这种结构:

DF$I3=apply(DF,1,function(x) DF2[x$"Index1",x$"Index2"])

但我犯了这个错误:

Error in x$Index2 : $ operator is invalid for atomic vectors 

我想得到一个像这样的数据框DF

   x1 x2 Index1 Index2  I3
1 001  T      1      2 1.0
2 002  V      3      1 0.3
3 003  C      1      4 5.0
4 004  D      4      1 0.4
5 005  M      6      1 0.6
6 006  N      7      3 4.0

根据I3DF2的值,在Index1中查找Index2的每个值。 dput()DFDF2是下一个:

DF=structure(list(x1 = c("001", "002", "003", "004", "005", "006"
), x2 = c("T", "V", "C", "D", "M", "N"), Index1 = c(1, 3, 1, 
4, 6, 7), Index2 = c(2, 1, 4, 1, 1, 3), I3 = c(1, 0.3, 5, 0.4, 
0.6, 4)), .Names = c("x1", "x2", "Index1", "Index2", "I3"), row.names = c(NA, 
-6L), class = "data.frame")

DF2=structure(list(a1 = c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7), a2 = c(1, 
0.9, 0.8, 0.7, 0.6, 0.5, 0.4), a3 = c(10, 9, 8, 7, 6, 5, 4), 
    a4 = c(5, 4, 3, 2, 1, 0, 6)), .Names = c("a1", "a2", "a3", 
"a4"), row.names = c(NA, -7L), class = "data.frame")

2 个答案:

答案 0 :(得分:2)

您可以使用matrix对象进行索引,如下所示:

DF2[as.matrix(DF[c("Index1","Index2")])]
#[1] 1.0 0.3 5.0 0.4 0.6 4.0

简化示例:

dat <- data.frame(one=1:5,two=6:10)
dat

#  one two
#1   1   6
#2   2   7
#3   3   8
#4   4   9
#5   5  10

mat <- cbind(c(1,3,5),c(1,2,1))
mat

#      row  col
#     [,1] [,2]
#[1,]    1    1
#[2,]    3    2
#[3,]    5    1

dat[mat]
#[1] 1 8 5

答案 1 :(得分:1)

有时知道为什么某些东西不起作用是有用的。本着这种精神,

DF$I3=apply(DF,1,function(x) DF2[x$"Index1",x$"Index2"])

有几个问题。

首先,apply(...)强制矩阵的第一个参数,根据定义,它必须具有相同数据类型的所有单元格。由于DF的前两列是字符,DF将被强制转换为所有字符,例如,DF$Index1将为c("1","3","1",...),这是无效的。您只需将DF的相关列传递给apply(...)即可解决该问题。这将被强制转换为所有数字的矩阵,这就是你想要的。

其次,apply(DF,1,function(x){...})DF的行传递为&#34;原子矢量&#34;,这意味着您可以将它们引用为,例如x[1],或x["Index1"],但不是x$Index1

将这些全部放在一起,任何这些表达

apply(DF[c("Index1","Index2")],1,function(x)DF2[x["Index1"],x["Index2"]])
# [1] 1.0 0.3 5.0 0.4 0.6 4.0

apply(DF[c("Index1","Index2")],1,function(x)DF2[x[1],x[2]])
# [1] 1.0 0.3 5.0 0.4 0.6 4.0

apply(DF[3:4],1,function(x)DF2[x[1],x[2]])
# [1] 1.0 0.3 5.0 0.4 0.6 4.0

产生所需的结果。

你的第一次尝试,

DF$I3=DF2[DF$"Index1",DF$"Index2"]

提取与DF$Index1对应的所有行以及与DF$Index2对应的所有列

说完这一切之后,最好的方法是在另一个答案中:使用矩阵索引。