【问题标题】:Change data.frame values to %将 data.frame 值更改为 %
【发布时间】:2021-06-15 13:22:03
【问题描述】:

如何将包含 NA 值的 df 的值替换为对行总和的贡献百分比?

例子:

# dummy df
a <- c("x","y","z")
b <- c(10,5,2)
c <- c("NA",1,"NA")
d <- c("NA",4,8)

dummy <- data.frame(a,b,c,d)
a b c
x 10 NA NA
y 5 1 4
z 2 NA 8

我想要什么:

a b c
x 100% NA NA
y 50% 10% 40%
z 20% NA 80%

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    首先,最好使用明确的 NA,而不是显示“NA”的字符串。

    其次,你可以使用dplyr的rowwise()across()来解决这个问题:

    library(scales)
    library(dplyr)
    
    # dummy df with explict NAs
    a <- c("x","y","z")
    b <- c(10,5,2)
    c <- c(NA,1, NA)
    d <- c(NA, 4,8)
    dummy <- data.frame(a,b,c,d)
      
    dummy %>% 
      # add column of sum by row
      rowwise() %>% 
      mutate(row_sum = sum(c_across(b:d), na.rm = TRUE),
             # divide each column by sum of row
             across(b:d, ~ percent(.x / row_sum))) %>% 
      ungroup() %>% 
      # remove sum column
      select(-row_sum)
    
    #  A tibble: 3 x 4
    #   a     b     c     d    
    #   <chr> <chr> <chr> <chr>
    # 1 x     100%  NA    NA   
    # 2 y     50%   10%   40%  
    # 3 z     20%   NA    80% 
    

    【讨论】:

      【解决方案2】:

      你可以这样做,

      cbind.data.frame(dummy[1], 10 * (dummy[-1]))
      
      #  a   b  c  d
      #1 x 100 NA NA
      #2 y  50 10 40
      #3 z  20 NA 80
      

      注意:您的列必须是数字

      【讨论】:

        【解决方案3】:

        你也可以这样用:

        library(dplyr)
        
        dummy %>%
          mutate(across(b:d, ~ ifelse(.x != "NA", paste0(as.numeric(.x) * 10, "%"), .x)))
        
          a    b   c   d
        1 x 100%  NA  NA
        2 y  50% 10% 40%
        3 z  20%  NA 80%
        

        【讨论】:

          【解决方案4】:

          我通过删除第一列、将 NA 替换为 0、进行计算然后重新附加第一列来解决问题。

          dummy[is.na(dummy)] <- 0 # sets na's as zeros
          
          header <- dummy[1] # stores 1st column
          
          df <- round(dummy[-1]/rowSums(dummy[-1])*100,digits=3) # calculates the %
          
          df <- cbind(header,dummy) # joins 1st column to the results 
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-01-07
            • 1970-01-01
            • 1970-01-01
            • 2020-03-12
            • 2013-01-24
            • 1970-01-01
            • 2011-03-24
            相关资源
            最近更新 更多