R语言 按行添加值并将其应用于单个行变量,同时保留其他变量和行

cvxl0en2  于 2023-03-05  发布在  其他
关注(0)|答案(3)|浏览(152)

我有一个 Dataframe 看起来像,

df <- data.frame(num1 = c('a','b','c','d')
                 ,num2 = c(1,2,3,4)
                 ,num3 = c(5,6,7,8)
                 ,num4 = c('x','y','b','d'))

希望输出从

num1  num2  num3 num4
a     1     5    x
b     2     6    y
c     3     7    b
d     4     8    d

num1  num2  num3 num4
a     10    26   x 
b     2     6    y
c     3     7    b
d     4     8    d

下面是在我自己的解决方案中实现该结果的示例

df <- data.frame(num1 = c('a', 'b', 'c', 'd'),
                 num2 = c(1, 2, 3, 4),
                 num3 = c(5, 6, 7, 8),
                 num4 = c('x', 'y', 'b', 'd'))

sum_summarised <- df %>% 
  filter(grepl('a|b|c',num1)) %>% 
  summarise(num2 = sum(num2), num3 = sum(num3))

df <- df %>% 
  mutate(num2 = if_else(num1 == 'a',sum_summarised$num2,num2))

df <- df %>% 
  mutate(num3 = if_else(num1 == 'a',sum_summarised$num3,num3))

实际上,对num 2/num 3列求和,并将总和应用于行a变量,同时保留变量b、c和d的原始行值以及num 4列值。
首选将使用dplyr -我已经尝试了group_byslicefilter组合的变种无济于事。任何帮助将非常感谢在这个独特的问题,我所面临的。谢谢!

axr492tv

axr492tv1#

另一种方法是使用rows_update()。这有点冗长,但我想说如果我们想构造更复杂的操作,它是值得的。下面我们调用rows_update(),在里面我们使用summarise(),首先定义我们想要连接的id列,然后定义我们想要用'across()更新的列,其他的一切都不会改变。

library(dplyr)

df %>% 
  rows_update(
    df %>%
      summarise(num1 = "a",
                across(num2:num3, sum)),
    by = "num1")

#>   num1 num2 num3 num4
#> 1    a   10   26    x
#> 2    b    2    6    y
#> 3    c    3    7    b
#> 4    d    4    8    d

我们还可以在tibble中执行更复杂的运算,例如,如果我们不想对c求和,我们可以filter()

df %>% 
  rows_update(
    df %>%
      filter(num1 != "c") %>% 
      summarise(num1 = "a",
                across(num2:num3, sum)),
    by = "num1")

#>   num1 num2 num3 num4
#> 1    a    7   19    x
#> 2    b    2    6    y
#> 3    c    3    7    b
#> 4    d    4    8    d

数据来自OP

df <- data.frame(num1 = c('a','b','c','d')
                 ,num2 = c(1,2,3,4)
                 ,num3 = c(5,6,7,8)
                 ,num4 = c('x','y','b','d'))

reprex package(v2.0.1)于2023年3月3日创建

wbgh16ku

wbgh16ku2#

由于您对dplyr有偏好,我们可以使用acrossif_else

library(dplyr)

df |>
  mutate(across(num2:num3, ~ if_else(num1 == "a", sum(.), .)))

输出:

num1 num2 num3 num4
1    a   10   26    x
2    b    2    6    y
3    c    3    7    b
4    d    4    8    d
    • 更新***,如果我只想对a、b和c求和(不是全部)并应用于a *:
library(dplyr)

df |>
  mutate(across(num2:num3, ~ if_else(num1 == "a", sum(.[num1 %in% c("a", "b", "c")]), .)))

输出:

num1 num2 num3 num4
1    a    6   18    x
2    b    2    6    y
3    c    3    7    b
4    d    4    8    d
tjvv9vkg

tjvv9vkg3#

一种方法是使用“dplyr”包中的transmute()

library(tidyverse)
df %>%
  transmute(num1, 
            num2 = c(sum(num2), num2[-1]), 
            num3 = c(sum(num3), num3[-1]), 
            num4)

  num1 num2 num3 num4
1    a   10   26    x
2    b    2    6    y
3    c    3    7    b
4    d    4    8    d

相关问题