加入数据帧以替换值

时间:2017-01-26 08:26:58

标签: r join

我正在用测试数据编写大量代码。目前我有这两个数据帧:

> abc
  BLOCK start end
1    B1     1   3
2    B2     4   6
3    B3     7   9
4    B4    10  12
> def
   V1 V2 V3 V4
r1 B1 B2 B3 B4
r2 B1 B2 B4 B3
r3 B1 B3 B4 B2
r4 B2 B3 B4 B1
> 

第一个数据帧abc包含BLOCK分类变量的值。例如,B1从1开始,以3结束(即1:3或1,2,3)。

我的目标是将abc数据框扩展到所有值,然后将其与def数据框一起加入。我已经尝试过加入,合并和不同的格式,但我没有成功。任何帮助将不胜感激。

所需的输出如下:

1   2   3   4   5   6   7   8   9   10  11  12
1   2   3   4   5   6   10  11  12  7   8   9
1   2   3   7   8   9   10  11  12  4   5   6
4   5   6   7   8   9   10  11  12  1   2   3

2 个答案:

答案 0 :(得分:1)

从零件构建。首先是给定块代码和块定义生成序列的函数:

> seqB
function(B,abc){b = abc[abc$BLOCK==as.character(B),];seq(b$start, b$end)}
> seqB("B2",abc)
[1] 4 5 6

然后在给定行号,块定义和输出行块序列的情况下创建输出的第N行的函数:

> rowN
function(N,def,abc){do.call(c,lapply(def[N,],seqB,abc=abc))}

> rowN(3,def,abc)
V11 V12 V13 V21 V22 V23 V31 V32 V33 V41 V42 V43 
  1   2   3   7   8   9  10  11  12   4   5   6 

最后,应用Nrow次并对所有内容进行输出:

> do.call(rbind,lapply(1:nrow(def),rowN,def=def,abc=abc))
     V11 V12 V13 V21 V22 V23 V31 V32 V33 V41 V42 V43
[1,]   1   2   3   4   5   6   7   8   9  10  11  12
[2,]   1   2   3   4   5   6  10  11  12   7   8   9
[3,]   1   2   3   7   8   9  10  11  12   4   5   6
[4,]   4   5   6   7   8   9  10  11  12   1   2   3

我怀疑你可以通过编写做到这一点def了在相当长的形式,加入到宽版的abc具有扩展序列,然后提取所有的数字和在右侧的矩阵重新排列行数和列数,但我不确定它会更快。

答案 1 :(得分:0)

与@Spacedman建议的方法不同。

首先让我们定义块

crt_Block <- paste0(abc$BLOCK,"<- seq(",abc$start,",",abc$end,")" )
for(i in 1:length(crt_Block) ) eval(parse(text = crt_Block[i]) )

接下来,我将def矩阵按行折叠成一个向量,用它们的数值替换块并构造回矩阵。

v <- as.vector(t(def))
vec <- eval(parse(text = paste0("c(", paste(v,collapse=","),")")))
matrix(vec,byrow = T, ncol=3*ncol(def) )

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,]    1    2    3    4    5    6    7    8    9    10    11    12
[2,]    1    2    3    4    5    6   10   11   12     7     8     9
[3,]    1    2    3    7    8    9   10   11   12     4     5     6
[4,]    4    5    6    7    8    9   10   11   12     1     2     3