根据一列移动数据框中的行

Move rows in a dataframe accordingly to one column

我希望将数据框中的特定行相应地移动到一列。

df <- read.table(text = 'ID Day Count
33012   9526    4
35004   9526    4
37006   9526    4
37008   9526    4
21009   1913    3
24005   1913    3
25009   1913    3
29002   12551   2
30001   12551   2
25009   14329   1
48007   9525    0
49002   1912    0
51003   12550   0
56001   12550   0', header = TRUE)

鉴于上述数据框,我想将 Count 列中带有 0 的行相应地移动到 Day 列,即 9526 之后的第 9525 天、1913 之后的 1912 天、12551 之后的 12550。

输出应该是:

ID       Day  Count
33012   9526    4
35004   9526    4
37006   9526    4
37008   9526    4
48007   9525    0
21009   1913    3
24005   1913    3
25009   1913    3
49002   1912    0
29002   12551   2
30001   12551   2
51003   12550   0
56001   12550   0
25009   14329   1

请忽略 ID 列。


与此主题相关的新问题:

Move rows in a dataframe accordingly to one column (2)

更新问题的答案

我想我找到了一个非常棒的解决方案来解决您更新后的问题:

df[order(match(df$Day+(z <- df$Count==0L),unique(df$Day[!z])),z),];
##       ID   Day Count
## 1  33012  9526     4
## 2  35004  9526     4
## 3  37006  9526     4
## 4  37008  9526     4
## 11 48007  9525     0
## 5  21009  1913     3
## 6  24005  1913     3
## 7  25009  1913     3
## 12 49002  1912     0
## 8  29002 12551     2
## 9  30001 12551     2
## 13 51003 12550     0
## 14 56001 12550     0
## 10 25009 14329     1

此解决方案按两件事排序:

1: 首先,它按 "canonical" Day 值排序。规范的 Day 值对于非零 Count 行取为 df$Day,对于零 Count 行取为 df$Day+1L。这是通过将规范 Day 值匹配到非零 Count 行的唯一规范 Day 值的向量来实现的,它还可以保留规范 [=] 的传入顺序14=] 值。规范的 Day 值是使用逻辑加法计算的,它将 FALSE 视为零,将 TRUE 视为一。 zero/non-zero 区别在局部变量 z 中实时捕获,免除了对该信息进行后续冗余计算的需要。

2: 其次,它将非零 Count 行排在零 Count 行之前。由于 z 已经在该行的前面计算过,我们可以简单地将它作为第二个参数传递给 order() 来执行此操作。当按逻辑向量排序时,FALSETRUE之前排序,因此它直接起作用。


原问题的答案

我想这就是您要找的:

df$vl <- ave(df$vl,df$id,FUN=function(x) sort(decreasing=T,x));
df;
##    id vl
## 1   C  5
## 2   C  3
## 3   C  2
## 4   C  2
## 5   A  5
## 6   A  5
## 7   A  4
## 8   A  2
## 9   B  4
## 10  B  2
## 11  B  1
## 12  B  1

以上对每个 id 组中的 vl 列进行排序,独立于其他 id 组。

数据

set.seed(1L);
df <- data.frame(id=rep(c('C','A','B'),each=4L),vl=sample(5L,12L,T));

对您问题的另一种解释是,您希望按 vl 列对整个 data.frame 进行排序,但在 vl 的每个唯一值中,您希望优先顺序其中 id 列中的唯一值出现在原始 data.frame 中(尽管并非所有 id 值都与每个唯一 vl 值一起表示)。方法如下:

df[order(-df$vl,match(df$id,unique(df$id))),];
##    id vl
## 1   C  5
## 5   A  5
## 6   A  5
## 7   A  4
## 9   B  4
## 2   C  3
## 3   C  2
## 4   C  2
## 8   A  2
## 10  B  2
## 11  B  1
## 12  B  1