如何将突变的圆柱重新定位在原始柱面旁边?

发布于 2025-01-18 07:03:46 字数 940 浏览 0 评论 0原文

我创建了一个函数,它可以跨列变异并从每个列创建新的命名列。新列被放置在数据框的右侧,而我希望它们与每个原始列相邻。我正在寻找一种解决方案,可以推广到可能使用此函数的任何数据帧,编写一个 select 语句来重新排序列对于我的用例来说不够自动。

test_data <- data.frame(data_col_1 = c(1,2,3),
                        data_col_2 = c(1,2,3),
                        data_col_3 = c(1,2,3),
                        another_column = c("a","b","c"))


perc_funct <- function(df, columns, numerator){
  
p_f <- function(x, numerator){
  
  (x/numerator)*100
}
    j <- df %>%
     mutate( across({{columns}}, 
                    .fns = list(perc = ~p_f(.x, numerator)),
                    .names = "{col}_{fn}"))# need to figure out a way to get the columns ordered 
return(j)
}

test_data %>% perc_funct(columns = starts_with("data"), numerator = 1)

当前输出将所有新列放在右侧。

我想要的

输出将每个新列放在每个旧列的右侧。 “data_col_1” “data_col_1_perc” “data_col_2” “data_col_2_perc” “data_col_3” “data_col_3_perc” “another_column”

I have made a function which mutates across columns and creates new named columns from each of them. The new colums are put to the right side of the dataframe whereas I would like to have them adjacent to each of the original columns. I am looking for a solution that will generalise to any dataframe this function might be used on, writing a select statement to reorder the columns is not automatic enough for my use case.

test_data <- data.frame(data_col_1 = c(1,2,3),
                        data_col_2 = c(1,2,3),
                        data_col_3 = c(1,2,3),
                        another_column = c("a","b","c"))


perc_funct <- function(df, columns, numerator){
  
p_f <- function(x, numerator){
  
  (x/numerator)*100
}
    j <- df %>%
     mutate( across({{columns}}, 
                    .fns = list(perc = ~p_f(.x, numerator)),
                    .names = "{col}_{fn}"))# need to figure out a way to get the columns ordered 
return(j)
}

test_data %>% perc_funct(columns = starts_with("data"), numerator = 1)

The output currently puts all the new colums to the right.

"data_col_1" "data_col_2" "data_col_3" "another_column" "data_col_1_perc" "data_col_2_perc" "data_col_3_perc"

The output I want puts each new colums to the right of each old column.
"data_col_1" "data_col_1_perc" "data_col_2" "data_col_2_perc" "data_col_3" "data_col_3_perc" "another_column"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

非要怀念 2025-01-25 07:03:46

我通常会在之后使用 select(sort(names(.))) 对列进行排序:

library(dplyr)

test_data %>% 
  perc_funct(columns = starts_with("data"), numerator = 1) %>% 
  select(sort(names(.)))

#>   data_col_1 data_col_1_perc data_col_2 data_col_2_perc data_col_3
#> 1          1             100          1             100          1
#> 2          2             200          2             200          2
#> 3          3             300          3             300          3
#>   data_col_3_perc
#> 1             100
#> 2             200
#> 3             300

reprex 包 (v2.0.1)

如果我想将其他列保留在同一位置怎么办?

只需将我的解决方案与其他 select 语句或 dplyr 动词嵌套在一起即可。作为中间步骤,您可能必须保存带有未排序列的数据框。

示例 1

这是一个包含其他三列的示例,我希望其中一些列位于最前面,一些列位于最后,而其他列则位于任意位置但保持在一起。

library(dplyr)

df <- 
  test_data %>% 
  mutate(first_col = 1, other_columns = 100, last_col = 999) %>%
  perc_funct(columns = starts_with("data"), numerator = 1)

# Unsorted:
df %>% names()
#> [1] "data_col_1"      "data_col_2"      "data_col_3"      "first_col"      
#> [5] "other_columns"   "last_col"        "data_col_1_perc" "data_col_2_perc"
#> [9] "data_col_3_perc"

# Sorted:
df %>% 
  select(
    first_col,
    df %>% select(starts_with("data")) %>% names() %>% sort(), 
    everything(),
    last_col
  ) 
#>   first_col data_col_1 data_col_1_perc data_col_2 data_col_2_perc data_col_3
#> 1         1          1             100          1             100          1
#> 2         1          2             200          2             200          2
#> 3         1          3             300          3             300          3
#>   data_col_3_perc other_columns last_col
#> 1             100           100      999
#> 2             200           100      999
#> 3             300           100      999

reprex 包 (v2.0.1) 于 2022 年 4 月 1 日创建

示例2

还有一种使用 col_bind() 的替代方法:

如果您只想将新列放在最后,但与创建它们的列一起排序,您还可以执行以下操作:

library(dplyr)
df %>% 
  select(
    -starts_with("data")
  ) %>% bind_cols(
    df %>% 
      select(
        df %>% select(starts_with("data")) %>% names() %>% sort()
      )
  )
#>   first_col other_columns last_col data_col_1 data_col_1_perc data_col_2
#> 1         1           100      999          1             100          1
#> 2         1           100      999          2             200          2
#> 3         1           100      999          3             300          3
#>   data_col_2_perc data_col_3 data_col_3_perc
#> 1             100          1             100
#> 2             200          2             200
#> 3             300          3             300

I typically sort the columns with select(sort(names(.))) afterwards:

library(dplyr)

test_data %>% 
  perc_funct(columns = starts_with("data"), numerator = 1) %>% 
  select(sort(names(.)))

#>   data_col_1 data_col_1_perc data_col_2 data_col_2_perc data_col_3
#> 1          1             100          1             100          1
#> 2          2             200          2             200          2
#> 3          3             300          3             300          3
#>   data_col_3_perc
#> 1             100
#> 2             200
#> 3             300

Created on 2022-04-01 by the reprex package (v2.0.1)

What if I have other columns I want to keep in the same spot?

It's just a matter of nesting my solution above together with other select statements or dplyr verbs. You might have to save the dataframe with the unsorted columns as a intermediate step.

Example 1

Here is an example with three other columns, where I want some to come first, some to come last, and others to come anywhere but stay together.

library(dplyr)

df <- 
  test_data %>% 
  mutate(first_col = 1, other_columns = 100, last_col = 999) %>%
  perc_funct(columns = starts_with("data"), numerator = 1)

# Unsorted:
df %>% names()
#> [1] "data_col_1"      "data_col_2"      "data_col_3"      "first_col"      
#> [5] "other_columns"   "last_col"        "data_col_1_perc" "data_col_2_perc"
#> [9] "data_col_3_perc"

# Sorted:
df %>% 
  select(
    first_col,
    df %>% select(starts_with("data")) %>% names() %>% sort(), 
    everything(),
    last_col
  ) 
#>   first_col data_col_1 data_col_1_perc data_col_2 data_col_2_perc data_col_3
#> 1         1          1             100          1             100          1
#> 2         1          2             200          2             200          2
#> 3         1          3             300          3             300          3
#>   data_col_3_perc other_columns last_col
#> 1             100           100      999
#> 2             200           100      999
#> 3             300           100      999

Created on 2022-04-01 by the reprex package (v2.0.1)

Example 2

There's also an alternative using col_bind():

If you just want your new columns last, but sorted together with the columns they were created from, you can also do something like:

library(dplyr)
df %>% 
  select(
    -starts_with("data")
  ) %>% bind_cols(
    df %>% 
      select(
        df %>% select(starts_with("data")) %>% names() %>% sort()
      )
  )
#>   first_col other_columns last_col data_col_1 data_col_1_perc data_col_2
#> 1         1           100      999          1             100          1
#> 2         1           100      999          2             200          2
#> 3         1           100      999          3             300          3
#>   data_col_2_perc data_col_3 data_col_3_perc
#> 1             100          1             100
#> 2             200          2             200
#> 3             300          3             300
ら栖息 2025-01-25 07:03:46

使用 dplyr(自版本 1.0.0 起)移动列的推荐方法是使用 relocate()relocate() 支持 tidyselect 语义,但重要的是仅作用于选定的列,而保留所有其他列。在您的情况下,您可以在以 data 开头的列上使用 grep()sort()

test_data <- data.frame(column_1 = 1:3,
                        data_col_1 = c(1,2,3),
                        data_col_2 = c(1,2,3),
                        data_col_3 = c(1,2,3),
                        another_column = c("a","b","c"))


test_data %>%
  perc_funct(columns = starts_with("data"), numerator = 1) %>%
  relocate(sort(grep("^data", names(.), value = TRUE)), .before = data_col_1)

  column_1 data_col_1 data_col_1_perc data_col_2 data_col_2_perc data_col_3 data_col_3_perc another_column
1        1          1             100          1             100          1             100              a
2        2          2             200          2             200          2             200              b
3        3          3             300          3             300          3             300              c

.before (或 .after)参数指定重新定位列的位置,在这种情况下,您可以将它们放置在 data_col_1 之前。

The recommended way to move columns using dplyr (since version 1.0.0) is to use relocate(). relocate() supports tidyselect semantics but importantly acts only on the selected column(s) leaving all other columns in place. In your case, you can grep() and sort() on the columns beginning with data.

test_data <- data.frame(column_1 = 1:3,
                        data_col_1 = c(1,2,3),
                        data_col_2 = c(1,2,3),
                        data_col_3 = c(1,2,3),
                        another_column = c("a","b","c"))


test_data %>%
  perc_funct(columns = starts_with("data"), numerator = 1) %>%
  relocate(sort(grep("^data", names(.), value = TRUE)), .before = data_col_1)

  column_1 data_col_1 data_col_1_perc data_col_2 data_col_2_perc data_col_3 data_col_3_perc another_column
1        1          1             100          1             100          1             100              a
2        2          2             200          2             200          2             200              b
3        3          3             300          3             300          3             300              c

The .before (or .after) argument specifies where to relocate the columns, in this case you can place them before data_col_1.

转瞬即逝 2025-01-25 07:03:46

另一种可能性是使用contains()和来自原始dataframe的列顺序

test_data <- data.frame(column_1 = 1:3,
                        data_col_1 = c(1,2,3),
                        data_col_2 = c(1,2,3),
                        data_col_3 = c(1,2,3),
                        another_column = c("a","b","c"))


test_data %>% perc_funct(columns = starts_with("data"), numerator = 1) %>% 
  select(contains(test_data %>% colnames()))

Another possibility would be to use contains() and the column order from the orginal dataframe

test_data <- data.frame(column_1 = 1:3,
                        data_col_1 = c(1,2,3),
                        data_col_2 = c(1,2,3),
                        data_col_3 = c(1,2,3),
                        another_column = c("a","b","c"))


test_data %>% perc_funct(columns = starts_with("data"), numerator = 1) %>% 
  select(contains(test_data %>% colnames()))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文