对两列进行排序,有条件地 select 值,然后 运行 累积频率
Sort two columns, conditionally select values, then run cumsum frequency
我的数据是这样的
a b c
1 1 0
1 2 8
2 1 0
2 2 2
3 1 3
3 2 3
4 1 7
4 2 4
5 1 3
5 2 5
6 1 1
6 2 8
7 1 1
7 2 2
我想对 a
和 c
列进行排序,以便 c
列中的每个偶数行都是 a 列中每一对的最大数字。然后我想获取这些值并将它们存储在一个新对象中。它应该看起来像这样。
a c b
1 8 2
2 2 2
3 3 2
4 7 1
5 5 2
6 8 2
7 2 2
您可以使用这种方法:
dat[order(dat$a, dat$c), ][c(FALSE, TRUE), ]
# a b c
# 2 1 2 8
# 4 2 2 2
# 6 3 2 3
# 7 4 1 7
# 10 5 2 5
# 12 6 2 8
# 14 7 2 2
另一种方法 dplyr
:
library(dplyr)
dat %>%
arrange(a, c) %>%
filter(duplicated(a))
这是一种方法。如果您的数据已经按 df 排列,我会使用 dplyr
做 slice(group_by(mydf, a), 2)
。但是,我不确定情况是否如此。我创建了一个示例并执行了以下操作。当 c
出现平局时,您似乎也考虑了 b
;你与 max(b) 发生争执。所以,我想这可能是一种方法。
library(dplyr)
foo <- data.frame(a = c(1, 1, 2, 2, 3, 3, 4, 4, 5, 5),
b = c(3, 5, 5, 6, 7, 1, 7, 3, 9, 2),
c = c(4, 0, 2, 6, 7, 7, 5, 2, 8, 1))
# a b c
#1 1 3 4
#2 1 5 0
#3 2 5 2
#4 2 6 6
#5 3 7 7
#6 3 1 7
#7 4 7 5
#8 4 3 2
#9 5 9 8
#10 5 2 1
group_by(arrange(foo, a, c, b), a) %>%
slice(2)
# a b c
#1 1 3 4
#2 2 6 6
#3 3 7 7
#4 4 7 5
#5 5 9 8
如果我对你的问题的理解正确,这个解决方案应该符合你的需要:
### Sample data
a <- rep(1:7, each = 2)
b <- rep(1:2, length(a)/2)
c <- c(0, 8, 0, 2, 3, 3, 7, 4, 3, 5, 1, 8, 1, 2)
abc <- cbind(a, b, c)
### Identify unique values of 'a'
unique_a <- unique(abc[, 1])
# Loop over all unique values of 'a'
t(sapply(unique_a, function(i) {
# Subset data by current unique entry
tmp_abc <- abc[which(abc[, 1] == i), ]
# Extract corresponding values of 'c'
tmp_val_c <- tmp_abc[, 3]
# If all values of 'c' are equal, take the 2nd entry (i.e. row)
if (tmp_val_c[1] == tmp_val_c[2]) {
id_max <- 2
# Else, identify the row with the maximum value of 'c'
} else {
id_max <- which.max(tmp_abc[, 3])
}
# Return row holding maximum value of 'c'
return(tmp_abc[id_max, c(1, 3, 2)])
}))
相应的 return 值如下所示:
a c b
[1,] 1 8 2
[2,] 2 2 2
[3,] 3 3 2
[4,] 4 7 1
[5,] 5 5 2
[6,] 6 8 2
[7,] 7 2 2
使用 data.table
包,您可以使用 setorder
或 setkey
按参考对数据进行排序(无需使用 <-
函数创建副本)
library(data.table)
setorder(setDT(df), a, c)[]
# a b c
# 1: 1 1 0
# 2: 1 2 8
# 3: 2 1 0
# 4: 2 2 2
# 5: 3 1 3
# 6: 3 2 3
# 7: 4 1 7
# 8: 4 2 4
# 9: 5 1 3
# 10: 5 2 5
# 11: 6 1 1
# 12: 6 2 8
# 13: 7 1 1
# 14: 7 2 2
然后您可以通过各种简单的方式实现您的目标,例如
df[duplicated(a)]
# a b c
# 1: 1 2 8
# 2: 2 2 2
# 3: 3 2 3
# 4: 4 2 4
# 5: 5 2 5
# 6: 6 2 8
# 7: 7 2 2
或者也许
df[, tail(.SD, 1), a]
# a b c
# 1: 1 2 8
# 2: 2 2 2
# 3: 3 2 3
# 4: 4 2 4
# 5: 5 2 5
# 6: 6 2 8
# 7: 7 2 2
或
df[, .SD[2], a]
# a b c
# 1: 1 2 8
# 2: 2 2 2
# 3: 3 2 3
# 4: 4 2 4
# 5: 5 2 5
# 6: 6 2 8
# 7: 7 2 2
P.S。如果要更改 列的顺序 ,也可以使用 setcolorder
函数通过引用来实现,例如
setcolorder(df, c("a", "c", "b"))
我的数据是这样的
a b c
1 1 0
1 2 8
2 1 0
2 2 2
3 1 3
3 2 3
4 1 7
4 2 4
5 1 3
5 2 5
6 1 1
6 2 8
7 1 1
7 2 2
我想对 a
和 c
列进行排序,以便 c
列中的每个偶数行都是 a 列中每一对的最大数字。然后我想获取这些值并将它们存储在一个新对象中。它应该看起来像这样。
a c b
1 8 2
2 2 2
3 3 2
4 7 1
5 5 2
6 8 2
7 2 2
您可以使用这种方法:
dat[order(dat$a, dat$c), ][c(FALSE, TRUE), ]
# a b c
# 2 1 2 8
# 4 2 2 2
# 6 3 2 3
# 7 4 1 7
# 10 5 2 5
# 12 6 2 8
# 14 7 2 2
另一种方法 dplyr
:
library(dplyr)
dat %>%
arrange(a, c) %>%
filter(duplicated(a))
这是一种方法。如果您的数据已经按 df 排列,我会使用 dplyr
做 slice(group_by(mydf, a), 2)
。但是,我不确定情况是否如此。我创建了一个示例并执行了以下操作。当 c
出现平局时,您似乎也考虑了 b
;你与 max(b) 发生争执。所以,我想这可能是一种方法。
library(dplyr)
foo <- data.frame(a = c(1, 1, 2, 2, 3, 3, 4, 4, 5, 5),
b = c(3, 5, 5, 6, 7, 1, 7, 3, 9, 2),
c = c(4, 0, 2, 6, 7, 7, 5, 2, 8, 1))
# a b c
#1 1 3 4
#2 1 5 0
#3 2 5 2
#4 2 6 6
#5 3 7 7
#6 3 1 7
#7 4 7 5
#8 4 3 2
#9 5 9 8
#10 5 2 1
group_by(arrange(foo, a, c, b), a) %>%
slice(2)
# a b c
#1 1 3 4
#2 2 6 6
#3 3 7 7
#4 4 7 5
#5 5 9 8
如果我对你的问题的理解正确,这个解决方案应该符合你的需要:
### Sample data
a <- rep(1:7, each = 2)
b <- rep(1:2, length(a)/2)
c <- c(0, 8, 0, 2, 3, 3, 7, 4, 3, 5, 1, 8, 1, 2)
abc <- cbind(a, b, c)
### Identify unique values of 'a'
unique_a <- unique(abc[, 1])
# Loop over all unique values of 'a'
t(sapply(unique_a, function(i) {
# Subset data by current unique entry
tmp_abc <- abc[which(abc[, 1] == i), ]
# Extract corresponding values of 'c'
tmp_val_c <- tmp_abc[, 3]
# If all values of 'c' are equal, take the 2nd entry (i.e. row)
if (tmp_val_c[1] == tmp_val_c[2]) {
id_max <- 2
# Else, identify the row with the maximum value of 'c'
} else {
id_max <- which.max(tmp_abc[, 3])
}
# Return row holding maximum value of 'c'
return(tmp_abc[id_max, c(1, 3, 2)])
}))
相应的 return 值如下所示:
a c b
[1,] 1 8 2
[2,] 2 2 2
[3,] 3 3 2
[4,] 4 7 1
[5,] 5 5 2
[6,] 6 8 2
[7,] 7 2 2
使用 data.table
包,您可以使用 setorder
或 setkey
按参考对数据进行排序(无需使用 <-
函数创建副本)
library(data.table)
setorder(setDT(df), a, c)[]
# a b c
# 1: 1 1 0
# 2: 1 2 8
# 3: 2 1 0
# 4: 2 2 2
# 5: 3 1 3
# 6: 3 2 3
# 7: 4 1 7
# 8: 4 2 4
# 9: 5 1 3
# 10: 5 2 5
# 11: 6 1 1
# 12: 6 2 8
# 13: 7 1 1
# 14: 7 2 2
然后您可以通过各种简单的方式实现您的目标,例如
df[duplicated(a)]
# a b c
# 1: 1 2 8
# 2: 2 2 2
# 3: 3 2 3
# 4: 4 2 4
# 5: 5 2 5
# 6: 6 2 8
# 7: 7 2 2
或者也许
df[, tail(.SD, 1), a]
# a b c
# 1: 1 2 8
# 2: 2 2 2
# 3: 3 2 3
# 4: 4 2 4
# 5: 5 2 5
# 6: 6 2 8
# 7: 7 2 2
或
df[, .SD[2], a]
# a b c
# 1: 1 2 8
# 2: 2 2 2
# 3: 3 2 3
# 4: 4 2 4
# 5: 5 2 5
# 6: 6 2 8
# 7: 7 2 2
P.S。如果要更改 列的顺序 ,也可以使用 setcolorder
函数通过引用来实现,例如
setcolorder(df, c("a", "c", "b"))