【问题标题】:how to replace a true value based on column name and additional table?如何根据列名和附加表替换真值?
【发布时间】:2021-08-27 02:36:31
【问题描述】:

我有以下数据。 v1:v4 是布尔值(真/假)

df1

id v1 v2 v3 v4
1  T  T  F  F
2  F  F  T  F
3  T  F  F  F
4  F  T  T  T

df2

var weight
v1   1
v2   4
v3   2
v4   5

我需要先根据变量名和辅助表df2替换每个变量的TRUE值。因此,例如,V1 列下的任何TRUE 都将变为1FALSE 将永远是 0。 稍后,status 变量将定义整行是否包含单个非零值或多个

df.out

id v1 v2 v3 v4 Status
1  1  4  0  0  Multiple
2  0  0  2  0  Single
3  1  0  0  0  Single
4  0  4  2  5  Multiple

【问题讨论】:

    标签: r


    【解决方案1】:

    这是tidyverse 的一个选项。循环across 'df2' 的'var' 列中指定的列名,replace TRUEvalues 由matching 与'var' 对应的'weight' 元素柱子。然后,我们使用rowSums根据每行非零元素的数量创建一个“状态”列

    library(dplyr)
    df1 %>% 
        mutate(across(df2$var, 
         ~ replace(., .,  df2$weight[match(cur_column(), df2$var)]))) %>%
        mutate(Status = case_when(rowSums(.[df2$var] > 0) > 1 
             ~ 'Multiple', TRUE ~ 'Single'))
    

    -输出

     id v1 v2 v3 v4   Status
    1  1  1  4  0  0 Multiple
    2  2  0  0  2  0   Single
    3  3  1  0  0  0   Single
    4  4  0  4  2  5 Multiple
    

    或使用base R

    df1new <- cbind(df1[1], setNames(df2$weight, 
               df2$var)[col(df1[df2$var])] * df1[df2$var])
    df1new$Status <- c("Single", "Multiple")[1 + (rowSums(df1new[df2$var] > 0) > 1)]
    

    -输出

    > df1new
      id v1 v2 v3 v4   Status
    1  1  1  4  0  0 Multiple
    2  2  0  0  2  0   Single
    3  3  1  0  0  0   Single
    4  4  0  4  2  5 Multiple
    

    或者另一个选项是来自base RMap

    lst1 <- Map(`*`, df1[df2$var], df2$weight)
    cbind(df1[1], lst1, Status =  c('Single', 'Multiple')[1 + (rowSums(df1[-1]) > 1)])
      id v1 v2 v3 v4   Status
    1  1  1  4  0  0 Multiple
    2  2  0  0  2  0   Single
    3  3  1  0  0  0   Single
    4  4  0  4  2  5 Multiple
    

    数据

    df1 <- structure(list(id = 1:4, v1 = c(TRUE, FALSE, TRUE, FALSE), v2 = c(TRUE, 
    FALSE, FALSE, TRUE), v3 = c(FALSE, TRUE, FALSE, TRUE), v4 = c(FALSE, 
    FALSE, FALSE, TRUE)), class = "data.frame", row.names = c(NA, 
    -4L))
    
    df2 <- structure(list(var = c("v1", "v2", "v3", "v4"), weight = c(1L, 
    4L, 2L, 5L)), class = "data.frame", row.names = c(NA, -4L))
    

    【讨论】:

      【解决方案2】:

      矩阵运算可以很简单xdf1ydf2

      x <- matrix(c(T,F,T,F,T,F,F,T,F,T,F,T,F,F,F,T), nrow =4 , ncol = 4)
      y <- c(1,4,2,5)
      z <- x %*% diag(y)
      z
      

      结果是

            [,1] [,2] [,3] [,4]
      [1,]    1    4    0    0
      [2,]    0    0    2    0
      [3,]    1    0    0    0
      [4,]    0    4    2    5
      

      出租

      Status<- x %*% diag(y)  %>%  as.logical(.>0) %>% matrix(.,4,4) %>% rowSums 
      
      res <- cbind(z,Status) %>% as.data.frame
      
        V1 V2 V3 V4 Status
      1  1  4  0  0      2
      2  0  0  2  0      1
      3  1  0  0  0      1
      4  0  4  2  5      3
      

      【讨论】:

        猜你喜欢
        • 2021-05-14
        • 2021-08-18
        • 1970-01-01
        • 1970-01-01
        • 2021-10-04
        • 2022-09-30
        • 2020-09-21
        • 1970-01-01
        • 2021-10-08
        相关资源
        最近更新 更多