提问人:Dani Quinchero 提问时间:11/14/2023 最后编辑:Dani Quinchero 更新时间:11/20/2023 访问量:57
创建一个新列,其中包含 R 上 tibble 中某些列的值的总和
Create a new column with the sum of the values from some columns in a tibble on R
问:
我有一个像 这样的小问题,我想按每行的值之和对一些列进行分组,用结果创建一个新列并替换总和的列,比如 .Table1
Table2
Table1
| Col_A | INTER | Col_B | Col_C | Col_D |
| ----- | ------- | ----- | ----- | ----- |
| 1 | [5-15) | 2 | 4 | 2 |
| 1 | [15-25) | 1 | 3 | 6 |
| 1 | [25-35) | 1 | 1 | 2 |
在此示例中,我将对 和 的值求和,将结果保存在 中。Col_B
Col_D
Col_E
Table2
| Col_A | INTER | Col_C | Col_E |
| --- | --- | --- | --- |
| 1 | [5-15) | 4 | 4 |
| 1 | [15-25) | 3 | 7 |
| 1 | [25-35) | 1 | 3 |
在我的真实数据中,我有几列(数值变量),它们有 NA。
我试过了:
Table2 <- Table1 %>% mutate(Col_E = rowSums(across(c(Col_B, Col_D))))
我收到此错误:
错误:列 有问题。
我。
x 必须使用有效的下标向量对列进行子集化。
x 下标的类型错误。 i 它必须是数字或字符。 i 组 1 中发生错误:Col_A = 1,INTER = “[5,15)”。mutate()
Col_E
Col_E = rowSums(...)
logical
答:
1赞
maike
11/14/2023
#1
结合之前注释中的一些输入,添加一个带有略微修改数据的 reprex 以解决 NA 删除问题,以及整洁的列选择示例以及如何预先指定新列的名称(如果您有几个要聚合的列组,例如,将所有内容保留在列表中以进行迭代,这很有用)。
在这里,我使用 select(- ...) 删除了在最后一步中聚合的列,但如果您只想保留新列,您可能还想研究 transmute(),但从我所读到的内容来看,这里的情况并非如此。
require(dplyr)
#> Loading required package: dplyr
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
df <- tribble(
~Col_A, ~INTER, ~ Col_B,~ Col_C, ~Col_D ,
1 , '[5-15)' , 2 , 4 , 2 ,
1 , '[15-25)' , 1 , 3 , NA ,
1 , '[25-35)' , 1 , 1 , 2
)
# pre-defined vector of column names
cols_add <- c('Col_B', 'Col_C', 'Col_D')
df %>%
mutate(!! col_sum := rowSums(across(all_of(cols_add)), na.rm = TRUE)) %>%
select(-all_of(cols_add))
#> # A tibble: 3 × 3
#> Col_A INTER Col_E
#> <dbl> <chr> <dbl>
#> 1 1 [5-15) 8
#> 2 1 [15-25) 4
#> 3 1 [25-35) 4
# you may also predefine the name of the result column, use !! and := in mutate
col_sum <- 'Col_E'
# using tidyselect with column index
df %>%
mutate(!! col_sum := rowSums(across(3:5), na.rm = TRUE)) %>%
select(-all_of(cols_add))
#> # A tibble: 3 × 3
#> Col_A INTER Col_E
#> <dbl> <chr> <dbl>
#> 1 1 [5-15) 8
#> 2 1 [15-25) 4
#> 3 1 [25-35) 4
# using tidyselect with regular expression
df %>%
mutate(!! col_sum := rowSums(across(matches('Col_[BCD]')), na.rm = TRUE)) %>%
select(-all_of(cols_add))
#> # A tibble: 3 × 3
#> Col_A INTER Col_E
#> <dbl> <chr> <dbl>
#> 1 1 [5-15) 8
#> 2 1 [15-25) 4
#> 3 1 [25-35) 4
# for multiple groups of columns to sum up
sum_spec <- list(
col_E = c('Col_A', 'Col_B'),
col_F = c('Col_C', 'Col_D')
)
df2 <- df
iwalk(sum_spec, ~{
df2 <<- df2 %>%
mutate( !! .y := rowSums(across(all_of(.x)), na.rm = TRUE)) %>%
select(-all_of(.x))
})
df2
#> # A tibble: 3 × 3
#> INTER col_E col_F
#> <chr> <dbl> <dbl>
#> 1 [5-15) 3 6
#> 2 [15-25) 2 3
#> 3 [25-35) 2 3
创建于 2023-11-14 with reprex v2.0.2
0赞
Dani Quinchero
11/20/2023
#2
我最终使用了创建要求和的变量列表的建议,但后来我只使用了简单的函数,因为我想以特定的方式对列进行排序(与 Table1 不同,示例数据中未说明)。select()
cols_add <- (Col_B, Col_D)
Table2 <- Table1 %>%
mutate(Col_E = rowSums(across(all_of(cols_add)), na.rm = TRUE)) %>%
select(Col_A, INTER, Col_C, Col_E)
但是,如果我希望 Table1 中列的默认顺序,我会使用它:
cols_add <- (Col_B, Col_D)
Table2 <- Table1 %>%
mutate(Col_E = rowSums(across(all_of(cols_add)), na.rm = TRUE)) %>%
select(!cols_add)
谢谢大家的帮助
评论
Table1 |> mutate(Col_E = Col_B + Col_D) |> select(-Col_B, -Col_D)
rowSums
across()
Table1 |> mutate(Col_E = rowSums(across(c(Col_B, Col_D))))
across()
mutate(Col_E = rowSums(across(c(Col_B, Col_D)), na.rm = TRUE)) %>% select(Col_A, INTER, Col_C, Col_E)
everything()