r - 如何将二元组拆分为 n 列的列对和行对

标签 r tidyverse

假设一个像这样的数据框:

# example dataset
df <- data.frame(
         rowid = 1:3,
         a = c("ax","cz","by"),
         b = c("cy","ax","bz"),
         c = c("bz","ay","cx")
      )

实现以下转型的有效方法是什么?

#> # A tibble: 3 x 4
#>  rowid      a       b       c
#>  <int>  <chr>   <chr>   <chr>
#>      1      x       z       y
#>      2      x       y       z
#>      3      y       z       x

目标是获取每个二元组的第二个字符,并将其按每行的第一个字符挑选的列进行排序。

如果可能,比较基本 R 和 Tidyverse 解决方案会很有用。

最佳答案

由于您正在寻找 Base 和 Tidyverse 的比较,我将提供一个基本解决方案:

tdf <- t(df[-1])
tdf[] <- substr(tdf, 2, 2)[order(col(tdf), tdf)]
df[-1] <- t(tdf)

#  rowid a b c
#1     1 x z y
#2     2 x y z
#3     3 y z x

解释这 3 个步骤:

.1) 获取 t() 的副本数据的转置版本
.2a) 获取order在每个字符串(隐式地第一个字母)的每一行( col() 现在,因为它被转置)
.2b) 使用此顺序从每个字符串的第二个字母中进行选择并覆盖 <-转置后的数据。
.3) t()转回原始结构并覆盖 <- df中的数据


30K 行基准

基础:

bigdf <- df[rep(1:3,10000),]
bigdf$rowid <- 1:30000

system.time({
    tdf <- t(bigdf[-1])
    tdf[] <- substr(tdf,2,2)[order(col(tdf), tdf)]
    bigdf[-1] <- t(tdf)
})
##   user  system elapsed 
##  0.023   0.000   0.023 

整洁:

bigdf <- df[rep(1:3,10000),]
bigdf$rowid <- 1:30000

library(dplyr)
library(tibble)
library(sjmisc)
library(stringr)

system.time({
    bigdf %>%
        rotate_df(cn=TRUE) %>%
        mutate(across(everything(),sort)) %>%
        rotate_df() %>%
        mutate(across(everything(),~str_sub(.,2,-1))) %>%
        rownames_to_column(var="rowid")
})
##   user  system elapsed 
## 21.177   0.047  21.244 

关于r - 如何将二元组拆分为 n 列的列对和行对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70970271/

相关文章:

r - 如何使用变量填充ggplot shapefile map ?

r - 根据频率过滤行

r - 我可以在 ggplot 条形图/柱形图上方添加分组线标签吗?

将制表符分隔的数据读入 R

r 过滤器() 问题 : plotly vs ggplot

r - 使用 tidyverse 从选择性 "Per Day"数字创建 "Per Month"行

r - 通过具有不同 ID 值的列扩展 R 中的数据框

r - 有条件地创建多个变量

r - 打印带有分栏符的小标题,如 v1.3.0 所示

r - 如何在加载包之前知道R中特定功能属于哪个包?