【问题标题】:R Creating new columns using for loop that generate vectors contains name of variablesR使用生成向量的for循环创建新列包含变量的名称
【发布时间】:2021-12-15 03:32:34
【问题描述】:

我有数据,我有包含变量名称的向量 使用这个向量我想创建包含变量总和的新列存在向量 向量是由 for 循环生成的,所以我不知道向量的数量,也不知道每个向量中存在的变量,即每次我生成包含不同变量名称的 vec 时

例如:假设我的循环将生成这三个向量: Vec when i=1 Vec when i=2 and Vec when i=3

Vec >
Vec >
Vec >
"A","B","C"
"B","D"
"D","E"

这是数据 >数据

Name      A    B    C    D    E
r1        1    5    12  21    15
r2        2    4     7  10     9
r3        5   15     6   9     6
r4        7    8     0   7    18

这是我应该得到的第一个结果(从第一个向量开始)

    Name      A    B    C     ABC      D      E          
     r1       1    5   12     18      21     15         
     r2       2    4    7     13      10      9        
     r3       5   15    6     26       9      6         
     r4       7    8    0     15       7     18         

这是最终结果

Name      A    B    C     ABC        D       BD      E          DE
 r1       1    5   12     18         21      26      15         36 
 r2       2    4    7     13         10      14       9         19
 r3       5   15    6     26          9      24       6         15
 r4       7    8    0     15          7      15      18         25

即 V1 包含变量“A”、“B”、“C”的名称,而 ABC 包含变量 A、B 和 C 的总和 同样适用于 BD(B 和 D 之和)和 DE(D 和 E 之和)

还要注意,我希望我的新列的名称是向量中存在的列的名称

如果您需要更多信息和更多解释或细节,请告诉我

【问题讨论】:

  • 最好包含一个可以复制粘贴的玩具套装,使用dput()。在您的情况下,这将导致structure(list(Name = c("r1", "r2", "r3", "r4"), A = c(1, 2, 5, 7), B = c(5, 4, 15, 8), C = c(12, 7, 6, 0), D = c(21, 10, 9, 7), E = c(15, 9, 6, 18)), class = c("tbl_df", "tbl", "data.frame" ), row.names = c(NA, -4L))。这让人们更容易找到解决方案。
  • 问题:插入的位置重要吗?即“ABC”是否应该始终放在 C 之后和 D 之前?

标签: r dataframe for-loop statistics


【解决方案1】:

purrr::reduce的解决方案:

library(tidyverse)

df <- data.frame(
  stringsAsFactors = FALSE,
              Name = c("r1", "r2", "r3", "r4"),
                 A = c(1L, 2L, 5L, 7L),
                 B = c(5L, 4L, 15L, 8L),
                 C = c(12L, 7L, 6L, 0L),
                 D = c(21L, 10L, 9L, 7L),
                 E = c(15L, 9L, 6L, 18L)
      )
vts <- list(c("A","B","C"),c("B","D"),c("D","E"))

reduce(vts, function(x,y)
  bind_cols(x, !!paste0(y,collapse = "") := rowSums(x[,y])), .init=df) 

#>   Name A  B  C  D  E ABC BD DE
#> 1   r1 1  5 12 21 15  18 26 36
#> 2   r2 2  4  7 10  9  13 14 19
#> 3   r3 5 15  6  9  6  26 24 15
#> 4   r4 7  8  0  7 18  15 15 25

【讨论】:

    【解决方案2】:
    
    library(purrr)
    library(stringr)
    
    v <- list(c("A","B","C"),c("B","D"),c("D","E"))
    
    express <- setNames(v, map(v, str_flatten)) %>% 
      imap(~ parse_expr(sprintf("rowSums(across(c(%s)))", paste(.x, collapse = ","))))
    
    df %>% 
      mutate(!!! express)
    

    输出

      Name A  B  C  D  E ABC BD DE
    1   r1 1  5 12 21 15  18 26 36
    2   r2 2  4  7 10  9  13 14 19
    3   r3 5 15  6  9  6  26 24 15
    4   r4 7  8  0  7 18  15 15 25
    

    【讨论】:

      猜你喜欢
      • 2021-12-18
      • 1970-01-01
      • 2020-05-15
      • 1970-01-01
      • 2021-09-01
      • 1970-01-01
      • 2018-02-18
      • 1970-01-01
      • 2021-12-14
      相关资源
      最近更新 更多