我希望在我的数据框中移动特定的行,相应地移动到一列。
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列。
与此主题相关的新问题:
答案 0 :(得分:1)
我认为我找到了一个非常酷的解决方案来解决您的更新问题:
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:首先,它按“规范”Day
值排序。对于非零Day
行,规范df$Day
值为Count
,对于零df$Day+1L
行,Count
值为Day
。这是通过将规范Day
值匹配到非零Count
行的唯一规范Day
值的向量中来实现的,这些值还用于保留规范{{的传入顺序1}}值。规范Day
值使用逻辑加法计算,将FALSE
视为零,将TRUE
视为一。零/非零区分在运行中在局部变量z
中捕获,从而免除了对该信息的后续冗余计算的需要。
2:其次,它在零Count
行之前命令非零Count
行。由于z
已在行中先前计算过,因此我们可以将其作为第二个参数传递给order()
来执行此操作。按逻辑向量排序时,FALSE
会在TRUE
之前排序,因此可以直接使用。
我认为这就是你要找的东西:
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
上述内容对每个vl
群组中的id
列进行排序,与其他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