【问题标题】:Transform a dataframe by counting the occurrences of a number in each row通过计算每行中出现的数字来转换数据框
【发布时间】:2021-07-04 20:42:10
【问题描述】:

所以我有这个 100,000 行和 7 列的数据框。每一列都是一个随机生成的数字。这是我制作该数据框的方法:

dataframe <-  t(replicate(100000,sample(1:8,7)))

我需要帮助的可能是应用一个函数或创建一个新的数据框来计算 2、3、5 或其他数字的出现次数并连续显示该数字。例如,如果我有数据框:

     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
 [1,]    1    4    6    2    8    3    7
 [2,]    7    2    6    3    5    8    1
 [3,]    6    4    7    5    8    2    3

我希望它变成:

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

每列的标签不是很重要,但也可以实现类似的东西。 感谢您的帮助。

【问题讨论】:

    标签: r dataframe transform apply


    【解决方案1】:

    带有apply 的基本 R 选项:

    对于每一行,将值转换为 'other',而不是 2、3 或 5。使用 table 计算每个值的数量。

    keep_values <- c(2, 3, 5)
    
    t(apply(dataframe, 1, function(x) {
      table(factor(replace(x, !x %in% keep_values, 'other'),c(keep_values, 'other')))
    }))
    
    #     2 3 5 other
    #[1,] 1 1 1     4
    #[2,] 1 1 1     4
    #[3,] 0 1 1     5
    #[4,] 1 1 1     4
    #[5,] 1 1 1     4
    #[6,] 1 0 1     5
    #...
    

    数据

    set.seed(123)
    dataframe <-  t(replicate(100000,sample(1:8,7)))
    head(dataframe)
    
    #     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
    #[1,]    7    8    3    6    2    4    5
    #[2,]    3    5    4    1    2    8    6
    #[3,]    5    3    7    1    4    8    6
    #[4,]    5    3    2    6    1    8    4
    #[5,]    4    6    1    3    5    7    2
    #[6,]    7    2    5    1    6    8    4
    

    【讨论】:

      【解决方案2】:

      这是 tidyverse 的一种方法:

      library(dplyr);library(purrr);
      dataframe %>%
        as.data.frame %>%
        mutate(map_dfc(list(Equal2 = 2,
                            Equal3 = 3,
                            Equal5 =5),~ rowSums(cur_data() == .x)),
               Other = sum(!str_detect(names(cur_data()),"Equal")) - rowSums(cbind(Equal2,Equal3,Equal5)))
      #   V1 V2 V3 V4 V5 V6 V7 Equal2 Equal3 Equal5 Other
      #1   1  8  3  4  6  5  7      0      1      1     5
      #2   3  4  1  5  2  6  8      1      1      1     4
      #3   4  2  6  3  7  5  1      1      1      1     4
      #4   2  3  5  1  8  7  6      1      1      1     4
      

      或者使用基础 R:

      dataframe <- as.data.frame(dataframe)
      IntCols <- sapply(list(Equal2 = 2, Equal3 = 3, Equal5 =5), 
                        function(x)rowSums(dataframe == x))
      Other <- ncol(dataframe) - rowSums(IntCols)
      cbind(dataframe,IntCols,Other)
      #   V1 V2 V3 V4 V5 V6 V7 Equal2 Equal3 Equal5 Other
      #1   1  8  3  4  6  5  7      0      1      1     5
      #2   3  4  1  5  2  6  8      1      1      1     4
      #3   4  2  6  3  7  5  1      1      1      1     4
      #4   2  3  5  1  8  7  6      1      1      1     4
      

      【讨论】:

      • 谢谢亲爱的坎贝尔先生,您的解决方案给我上了宝贵的一课。
      猜你喜欢
      • 2017-01-19
      • 2021-05-22
      • 2021-08-02
      • 1970-01-01
      • 2022-11-14
      • 2019-05-13
      • 1970-01-01
      • 1970-01-01
      • 2011-05-20
      相关资源
      最近更新 更多