我有一个数据框,其中有些行需要重新排序。例如:
df <- data.frame(name = c(1,1,1,1,1,2,2,2,2,2),
id = c("s","s","s","i","s","s","i","s","s","s"),
var1 = c(3,5,6,4,-7,2,1,-1,3,-6),
var2 = c(2,6,-7,5,-9,7,3,2,4,-9))
在此数据框中,id == "i"
需要重新排序的行。重新排序应仅通过比较组内其他行的值来完成(在这种情况下,列name
可用于group_by
)。重新排序的条件如下,例如。如果要检查的当前行是id == "i"
的行,则检查是否:
var1 < lead(var1) & var1 > lag(var1) & var2 < lead(var2) & var2 > lag(var2)
如果为FALSE则表示应该移动此行,直到此条件为TRUE。
重新排序后,最终产品应为:
df_output <- data.frame(name = c(1,1,1,1,1,2,2,2,2,2),
id = c("s","i","s","s","s","s","s","i","s","s"),
var1 = c(3,4,5,6,-7,2,-1,1,3,-6),
var2 = c(2,5,6,-7,-9,7,2,3,4,-9))
请注意,在第一组中id == "i"
从第4位移到第2位的行,而在第二组中,它已从第2位移到第3位。
如果可能,可以使用tidyverse
完成此操作(如果没有,那么可以使用JSON.stringify(jdata);
)吗?
答案 0 :(得分:0)
也许,那样?但我并没有看出你用“我做了什么”做了什么。没有地方去的地方或多个地方的行。如果事情会变得更加简单,那么事情就会变得更加简单。行被命令。
dfs <- filter(df, id=="s")
dfi <- filter(df, id=="i")
dfs$x <- (!is.na(lead(dfs$name)) & dfs$name==lead(dfs$name) & dfs$var1<lead(dfs$var1) & dfs$var2<lead(dfs$var2)) |
(!is.na(lag(dfs$name)) & dfs$name==lag(dfs$name) & dfs$var1>lag(dfs$var1) & dfs$var2>lag(dfs$var2) )
dfs$y <- row.names(dfs)
dfs1 <- filter(dfs,x) %>% select(-x)
dfs0 <- filter(dfs,!x) %>% select(-x)
dfi$y <- ""
df2 <- arrange(rbind(dfs1,dfi),name,var1,var2)
df2$y <- ifelse(df2$y=="",paste0(lag(df2$y),",",row.names(df2)),df2$y)
df_output <- arrange(rbind(df2,dfs0),y) %>% select(-y)
答案 1 :(得分:0)
作为IMO,检查我将使用onyl var1
的位置的两个变量是不可能的/ neseccary。
library(tidyverse)
df %>%
group_by(name) %>%
mutate(gr1=1:n()) %>%
mutate(gr2=first(which(var1 < var1[id =="i"]))) %>%
mutate(gr3= ifelse(id=="i", gr2+0.1, gr1)) %>%
ungroup() %>%
arrange(name, gr3) %>%
select(-starts_with("gr"))
# A tibble: 10 x 4
name id var1 var2
<dbl> <fct> <dbl> <dbl>
1 1 s 3 2
2 1 i 4 5
3 1 s 5 6
4 1 s 6 -7
5 1 s -7 -9
6 2 s 2 7
7 2 s -1 2
8 2 i 1 3
9 2 s 3 4
10 2 s -6 -9
我们的想法是找出每个name
组的第一个var1
值小于&#34; i
&#34;使用first
的值。最后使用gr
更新排列向量ifelse
并进行排列。