R语言 拆分字符向量,其中每个不同元素具有相等数量的bin

roqulrg3  于 2023-11-14  发布在  其他
关注(0)|答案(7)|浏览(154)
x <- rep(c("A","B","C"),times=c(6,8,3))
 "A" "A" "A" "A" "A" "A" "B" "B" "B" "B" "B" "B" "B" "B" "C" "C" "C"

字符串
我正在努力创建一个向量,对应于每个字母被分成3个箱子:

(A A A A A A  B B B B B B B B  C C C)
x_bin = 1 1 2 2 3 3  1 1 1 2 2 2 3 3  1 2 3


在这个例子中,我可以通过组合每2个值将A划分为3个bin。我可以通过组合3,3和2个值将B划分为3个bin。我只能通过组合1个值将C划分为3个bin。
我试过cutdplyr,但cut只适用于数字数据,它不能按照我想要的方式切割。

vsnjm48y

vsnjm48y1#

我们可以使用ave来按字母分组,然后使用rep(1:3, length.out=)来获得正确的长度。这保证了编号的组(每个字母)将相等平衡或偏离不超过1。

ave(rep(1L, length(x)), x, FUN = function(z) rep(1:3, length.out = length(z)))
#  [1] 1 2 3 1 2 3 1 2 3 1 2 3 1 2 1 2 3

字符串
如果你想要所有的1,2秒,等等,那么我们可以sort它们:

ave(rep(1L, length(x)), x, FUN = function(z) sort(rep(1:3, length.out = length(z))))
#  [1] 1 1 2 2 3 3 1 1 1 2 2 2 3 3 1 2 3


验证:

ave(rep(1L, length(x)), x, FUN = function(z) sort(rep(1:3, length.out = length(z)))) |>
  all.equal(x_bin)
# [1] TRUE


数据

x <- rep(c("A","B","C"),times=c(6,8,3))
x_bin <- c(1, 1, 2, 2, 3, 3, 1, 1, 1, 2, 2, 2, 3, 3, 1, 2, 3)

vyswwuz2

vyswwuz22#

  • ave中尝试rep
ave(
    seq_along(x),
    x,
    FUN = \(v) {
        rep(1:3,
            each = ceiling(length(v) / 3),
            length.out = length(v)
        )
    }
)

字符串

  • 或者,在ave中使用matrix的另一个技巧
ave(
    seq_along(x),
    x,
    FUN = \(v)
    col(matrix(nrow = ceiling(length(v) / 3), ncol = 3))[seq_along(v)]
)


它应该给予

jfgube3f

jfgube3f3#

**1)**我们可以这样使用ave/cut:

ave(x == x, x, FUN = \(x) cut(seq_along(x), 3))
## [1] 1 1 2 2 3 3 1 1 1 2 2 3 3 3 1 2 3

字符串

**2)**另一种可能性是unlist/tapply/cut:

unlist(tapply(x, x, \(x) cut(seq_along(x), 3, FALSE)))
## A1 A2 A3 A4 A5 A6 B1 B2 B3 B4 B5 B6 B7 B8 C1 C2 C3 
##  1  1  2  2  3  3  1  1  1  2  2  3  3  3  1  2  3

更新

对(1)进行了轻微改进,并增加了(2)。

rkkpypqq

rkkpypqq4#

x <- rep(c("A","B","C"),times=c(6,8,3))
xdf <- data.frame(x = x)

library(tidyverse)
xdf |> group_by(x) |> mutate(bin = rep(1:3, length.out = n())) |> arrange(x, bin)

字符串

x       bin
   <chr> <int>
 1 A         1
 2 A         1
 3 A         2
 4 A         2
 5 A         3
 6 A         3
 7 B         1
 8 B         1
 9 B         1
10 B         2
11 B         2
12 B         2
13 B         3
14 B         3
15 C         1
16 C         2
17 C         3

nxagd54h

nxagd54h5#

rle + rep

with(rle(x),
     sapply(seq(length(values)), 
            \(z) rep(1:3, 
                     each = ceiling(lengths[z] / 3), 
                     length.out = lengths[z]))
     ) |> 
  unlist()

#[1] 1 1 2 2 3 3 1 1 1 2 2 2 3 3 1 2 3

字符串

uyhoqukh

uyhoqukh6#

times <- c(6,8,3)
x <- rep(c("A","B","C"),times=times)
CUT <- ceiling(times / 3)
x_bin <- unlist(sapply(CUT, function(x)  rep(seq(3), each = x)))

x_bin
#>  [1] 1 1 2 2 3 3 1 1 1 2 2 2 3 3 3 1 2 3

字符串
创建于2023-11-10使用reprex v2.0.2

bksxznpy

bksxznpy7#

试试这个

> table(x) |> Map(\(...) sort(rep_len(...)), list(1:3), length.out=_) |> unlist()
 [1] 1 1 2 2 3 3 1 1 1 2 2 2 3 3 1 2 3

字符串
list(1:3)中定义bin的长度n=3。

相关问题