【问题标题】:Creating multiple columns by computation in R在 R 中通过计算创建多列
【发布时间】:2020-11-10 19:59:31
【问题描述】:

假设我有一个 100 X 100 的数据框,这是我的数据的一个小样本

df<-read.table (text=" Id   san1    san2    san3
1   A   A   A
2   A   A   A
3   A   M   M
4   M   A   A
", header=TRUE)

我想先转置它。并计算行的总和,然后创建两个新列,如下所示

San     1   2   3   4   A   M
san1    A   A   A   M   3   1
san2    A   A   M   A   3   1
san3    A   A   M   A   3   1

我使用了df(t)转置,然后我使用了mutate和rowsums,但它对我不起作用。

【问题讨论】:

    标签: r


    【解决方案1】:

    另一种基础 R 解决方案:

    A <- data.frame(t(df[-1]))
    names(A) <- df[,1]
    cbind(A, as.data.frame.matrix(t(table(stack(df[-1])))))
         1 2 3 4 A M
    san1 A A A M 3 1
    san2 A A M A 3 1
    san3 A A M A 3 1
    

    【讨论】:

      【解决方案2】:

      这是dplyr 解决方案:

      library(dplyr)
      
      df %>% 
        pivot_longer(-Id) %>% 
        pivot_wider(names_from = Id, values_from = value) %>% 
        rename(San = name) %>% 
        mutate(A = rowSums(. == "A"),
               M = rowSums(. == "M"))
      

      这给了我们:

        San   `1`   `2`   `3`   `4`       A     M
        <chr> <chr> <chr> <chr> <chr> <dbl> <dbl>
      1 san1  A     A     A     M         3     1
      2 san2  A     A     M     A         3     1
      3 san3  A     A     M     A         3     1
      

      【讨论】:

        【解决方案3】:

        我们可以使用

        library(data.table)
        library(tidyr)
        data.table::transpose(df, make.names = 'Id', keep.names = 'San') %>%
             mutate(A = rowSums(.[-1] == 'A'), M = rowSums(.[2:5] == 'M'))
        

        -输出

        #    San 1 2 3 4 A M
        #1 san1 A A A M 3 1
        #2 san2 A A M A 3 1
        #3 san3 A A M A 3 1
        

        【讨论】:

        • @user330 是否与您帖子中的数据相同
        • 错误:意外'=' in:“data.table::transpose(df, make.names = 'Id', keep.names = 'San') %>% mutate(1 ="
        • A 和 M 假设,我想将它用于任何二进制数据,例如 0,1
        • @user330 在这种情况下,你可以做 rowSums(.[2:5])rowSums(!.[2:5])
        • 错误:意外')' in: "data.table::transpose(df, make.names = 'Id', keep.names = 'San') %>% mutate(A =rowSums (.[2:5]), M = rowSums(!.[2:5])))"
        【解决方案4】:

        这是你想要的吗?

        a_col <- rowSums(t(df)=="A")
        a_col[1] <- "A"
        m_col <- rowSums(t(df)=="M")
        m_col[1] <- "M"
        cbind(t(df), a_col, m_col)
        

        【讨论】:

        • 对不起,它对我不起作用,因为它没有反映我的输出。也不适用于大数据
        【解决方案5】:

        另一种解决方案独立于AM 和使用tablemap_dfr 的剩余值,通过purrr 提供:

        library("tidyverse")
        df <- read.table (text = " Id   san1    san2    san3
        1   A   A   A
        2   A   A   A
        3   A   M   M
        4   M   A   A
        ", header = TRUE)
        df %>%
            pivot_longer(-Id) %>%
            pivot_wider(names_from = Id, values_from = value) %>%
            rename(San = name) %>%
            bind_cols(map_dfr(df, table)[-1, -c(1:nrow(df))])
        

        结果

        # A tibble: 3 x 7
          San   `1`   `2`   `3`   `4`   A       M      
          <chr> <chr> <chr> <chr> <chr> <table> <table>
        1 san1  A     A     A     M     3       1      
        2 san2  A     A     M     A     3       1      
        3 san3  A     A     M     A     3       1 
        

        更有趣的例子

        添加讨厌的Z 值。

        df_two <- df
        df_two[2,3] <- "Z"
        
        sum_those_letters <- function(.data, nice_id_col = Id, pretty_name = "San") {
            .data %>%
                pivot_longer(-{{nice_id_col}}) %>%
                pivot_wider(names_from = {{nice_id_col}}, values_from = value) %>%
                rename(pretty_name = name) %>%
                bind_cols(map_dfr(df_two, table)[-1, -c(1:nrow(.data))])
        }
        

        结果

        sum_those_letters(df_two, Id)
        
        # A tibble: 3 x 8
          San   `1`   `2`   `3`   `4`   A       M       Z      
          <chr> <chr> <chr> <chr> <chr> <table> <table> <table>
        1 san1  A     A     A     M     3       1       NA     
        2 san2  A     Z     M     A     2       1        1     
        3 san3  A     A     M     A     3       1       NA 
        

        【讨论】:

        • 对不起,它不适用于我的数据,我没有在我的 cloumns 中得到总和
        • @user330 我已经包含了数据,它来自你的帖子。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-09-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多