R:从长到宽,顺序匹配对

R: long to wide with sequential matching pairs

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

现在我假设要开始,必须生成一个新因素,为每个 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 

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)