R:具有顺序匹配对的长到宽

时间:2018-03-20 17:20:26

标签: r transpose tidyr reshape2

我的数据如下所示 str grp 中重复4次。目标是将 out 变量转置为两列,与str的顺序匹配对相关联。例如,str" dat"在第1行应该与第3行匹配。然后我们转到str" axy"在第2行与第9行匹配。

现在我假设开始时必须生成一个新因子,循环并编码每个str的第一个和第二个实例,我应该可以做到这一点,只要有一个简单的方法检查字符串匹配,但任何替代方法都会有所帮助。

Grp  str out
1    dat   45
1    axy   76
1    dat   55
1    bte   61
1    cny   41
1    bte   34
1    cny   67
1    dat   32
1    axy   59
1    cny   12
1    dat   51
1    cny   50
1    bte   52
1    axy   38
1    bte   17
1    axy   78
2 ....

输出看起来像这样,每个Grp有8行。

Grp  str1  out1 str2 out2
1    dat     45   dat    55
1    axy     76   axy    59
1    bte     61   bte    34
1    cny     41   cny    67
1    dat     32   dat    51
1    cny     12   cny    50
1    bte     52   bte    17
1    axy     38   axy    78 

或者我想这样,

Grp  str1  out1 out2
1    dat     45   55
1    axy     76   59
1    bte     61   34
1    cny     41   67
1    dat     32   51
1    cny     12   50
1    bte     52   17
1    axy     38   78 

1 个答案:

答案 0 :(得分:1)

splitlapply在这里很合适:

foo <- lapply(split(df, df$str), function(x){
  x$ind <- rep(1:2, nrow(x)/2);
  x
})
foo <- do.call(rbind, foo)
foo <- split(foo[, -4], foo[,4])
foo <- data.frame(foo[[1]], foo[[2]])[, -c(4,5)]
names(foo)[c(3,4)] <- c("out1", "out2")
foo
       Grp str out1 out2
axy.2    1 axy   76   59
axy.14   1 axy   38   78
bte.4    1 bte   61   34
bte.13   1 bte   52   17
cny.5    1 cny   41   67
cny.10   1 cny   12   50
dat.1    1 dat   45   55
dat.8    1 dat   32   51

如果您希望输出与问题中显示的所需输出具有相同的行顺序,请尝试以下操作:

foo2 <- foo[order(as.numeric(gsub("\\D", "", rownames(foo)))), ]
rownames(foo2) <- NULL
foo2
  Grp str out1 out2
1   1 dat   45   55
2   1 axy   76   59
3   1 bte   61   34
4   1 cny   41   67
5   1 dat   32   51
6   1 cny   12   50
7   1 bte   52   17
8   1 axy   38   78

df是您的data.frame:

df <- read.table(text="Grp  str out
1    dat   45
                 1    axy   76
                 1    dat   55
                 1    bte   61
                 1    cny   41
                 1    bte   34
                 1    cny   67
                 1    dat   32
                 1    axy   59
                 1    cny   12
                 1    dat   51
                 1    cny   50
                 1    bte   52
                 1    axy   38
                 1    bte   17
                 1    axy   78
                 ", header=TRUE)