将数据帧中的行相应地移动到一列 [英] Move rows in a dataframe accordingly to one column

查看:121
本文介绍了将数据帧中的行相应地移动到一列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望在数据框中移动特定的行,相应地列出一列。

  df<  -  read.table (text ='ID日数
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)

鉴于上述数据框,我想移动在列列中有0的行相应于列日,即9526之后的第9525年,1913年后的1912年,12551之后的12550。



输出应为:

  ID日数
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列。






与此主题相关的新问题: / p>

将数据框中的行相应地移动到一列(2)

解决方案

更新问题的答案



我觉得我发现一个非常酷的解决方案,更新的问题:

  df [order(match(df $ Day +(z<  -  df $ Count == 0L),unique(df $ Day [!z])),z),]; 
## ID日数
## 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:首先,它按照规范 Day 的值排序。规范的 Day 值被视为 df $ Day 为非零计数行和 df $ Day + 1L 为零计数行。这是通过将规范的 Day 值与唯一的规范 Day 非零 Count rows,它还用于保留规范的 Day 值的传入顺序。使用逻辑加法计算规范 Day 值,将$ code> FALSE 视为零, TRUE 一个。零/非零区分被即时捕获在局部变量 z 中,从而免除后续冗余计算的信息。



2:其次,它在0 之前订购非零 Count 计数行。由于 z 已经在行中较早计算,我们可以简单地将其作为第二个参数传递给 order()去做这个。当通过逻辑向量排序时, FALSE TRUE 之前排序,因此它可以直接工作。






原始问题的答案



我认为这是你要找的:

  df $ vl < -  ave(df $ vl,df $ id,FUN = function(x)sort 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 组中的code> 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 之前,您要更喜欢在原始data.frame中发生 id 列中的唯一值的顺序(尽管事实上并不是所有的 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


I am looking to move specific rows in my 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)

Given the above dataframe, I would like move the rows with 0s in the Count column accordingly to the column Day, i.e. day 9525 after 9526, 1912 after 1913, 12550 after 12551.

The output should be:

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

Please ignore the ID column.


New question related to this topic:

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

解决方案

Answer to updated question

I think I found a really cool solution to your updated question:

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

This solution orders by two things:

1: First, it orders by the "canonical" Day value. The canonical Day value is taken as df$Day for non-zero Count rows, and df$Day+1L for zero Count rows. This is accomplished by matching the canonical Day values into a vector of unique canonical Day values of the non-zero Count rows, which also functions to preserve the incoming order of the canonical Day values. The canonical Day values are computed using logical addition, which treats FALSE as zero and TRUE as one. The zero/non-zero distinction is captured in a local variable z on-the-fly, absolving the need for subsequent redundant computation of that information.

2: Second, it orders the non-zero Count rows before the zero Count rows. Since z has already been computed earlier in the line, we can simply pass it as the second argument to order() to do this. When ordering by a logical vector, FALSE is ordered before TRUE, thus it works directly.


Answer to original question

I think this is what you're looking for:

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

The above sorts the vl column within each id group, independently of the other id groups.

Data

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


Another interpretation of your question is that you want to sort the entire data.frame by the vl column, but within each unique value of vl, you want to prefer the order in which the unique values in the id column occur in the original data.frame (notwithstanding the fact that not all id values are represented alongside each unique vl value). Here's how that can be done:

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

这篇关于将数据帧中的行相应地移动到一列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆