大家好我想用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
我有两列Index1
和Index2
。在这些列中,我想要在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
根据I3
和DF2
的值,在Index1
中查找Index2
的每个值。 dput()
版DF
和DF2
是下一个:
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")
答案 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
对应的所有列。
说完这一切之后,最好的方法是在另一个答案中:使用矩阵索引。