【问题标题】:Relocate based on first none zero value with dplyr使用 dplyr 基于第一个非零值重定位
【发布时间】:2021-09-06 18:58:51
【问题描述】:

我想根据字符串名称和每列中的第一个非零值对列进行排序。

假设我有以下数据:

col1_A  col2_A col1_B col2_B 
   0       0      0      0   
   0       2      0      4 
   3       12     1      1  

我需要以这样一种方式对它们进行排序,即名称包括“_A”的列放在“_B”之前,然后第一个非零值的列先出现。预期输出将是:

col2_A  col1_A col1_B col2_B 
   0       0      0      0   
   2       0      4      0 
   12      3      1      1  

这是用于复制的示例数据。

df = data.frame('col1_A'=c(0,0,3),'col2_A'=c(0,2,12),'col1_B'=c(0,0,1),'col2_B'=c(0,4,1))

更新:

列名只是示例,唯一的最后一个字符很重要!因此我现在将它们更改为这样以避免混淆。

【问题讨论】:

  • @RonakShah 是的,谢谢!

标签: r dplyr


【解决方案1】:
library(tidyverse)
df = data.frame('col1_A'=c(0,0,3),'col2_A'=c(0,2,12),'col3_B'=c(0,0,1),'col4_B'=c(0,4,1))


df %>% 
  imap_chr(~ str_c(str_extract(.y, "\\w$"),
                   which(.x != 0)[1])) %>% 
  enframe() %>% 
  arrange(value) %>% 
  {df[.$name]}
#>   col2_A col1_A col4_B col3_B
#> 1      0      0      0      0
#> 2      2      0      4      0
#> 3     12      3      1      1

reprex package (v2.0.1) 于 2021-09-06 创建

【讨论】:

  • 谢谢@shs,太棒了。它需要的小修复是,col4_B 也应该放在 col3_B 之前。
  • 对不起,我把问题理解为按第一个出现的非零值排序,我改了
  • 谢谢!这对于虚拟数据集非常有效。但是,我不是 str_extract 方面的专家,因此将其应用于我的实际数据集有点挑战。我有“_cost”和“_output”而不是“A”和“_B”,而在“”之前不是按数字排序的,它是随机字符。如何根据以“_cost”或“_output”结尾的str_extract?
【解决方案2】:

这是使用split.default的另一种方式-

purrr::map_dfc(split.default(df, sub('.*_', '', names(df))), function(x) {
  x[order(sapply(x, function(x) match(TRUE, x !=0)))]
})

#  col2_A col1_A col2_B col1_B
#1      0      0      0      0
#2      2      0      4      0
#3     12      3      1      1

sub 只保留输出中重要的最后一个字符。我们相应地拆分数据。

sub('.*_', '', names(df))
#[1] "A" "A" "B" "B"

对于每个组(AB),我们提取第一个非零值(match(TRUE, x!= 0))的位置并使用order 重新排列数据帧。 map_dfc 用于将数据框列表合并到一个合并的数据框中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多