【问题标题】:Logical check on rows with column index varying对列索引不同的行进行逻辑检查
【发布时间】:2018-03-14 07:04:26
【问题描述】:

我一直在用 R 语言为这个具有大数据集的特定任务开发代码

示例数据框如下所示:

   mon  abb Apr May Jun Jul Aug Sep Oct Nov
    5   May 2   4   2   5   0   0   7   0
    5   May 6   5   1   1   3   0   6   4
    5   May 3   1   0   1   1   2   8   8
    7   Jul 5   4   1   0   0   0   9   1
    7   Jul 3   3   4   3   4   4   9   9
    7   Jul 4   2   3   3   1   2   7   4
    7   Jul 4   1   4   2   3   5   4   3
    6   Jun 4   0   4   3   3   6   5   5
    7   Jul 4   4   5   3   4   8   8   8
    5   May 4   -1  6   4   4   9   5   4
    7   Jul 4   -2  4   4   2   6   6   9

对于与列名月份匹配的列 abb 中月份中的每一行,相应单元格中的数字将与后续数字进行比较,并且列 count 的创建次数小于另一个列中的数字细胞。希望清楚

Output would look like
mon abb Apr May Jun Jul Aug Sep Oct Nov Count
5   May 2   4   2   5   0   0   7   0   2
5   May 6   5   1   1   3   0   6   4   1
5   May 3   1   0   1   1   2   8   8   3
7   Jul 5   4   1   0   0   0   9   1   2
7   Jul 3   3   4   3   4   4   9   9   4
7   Jul 4   2   3   3   1   2   7   4   2
7   Jul 4   1   4   2   3   5   4   3   4
6   Jun 4   0   4   3   3   6   5   5   3
7   Jul 4   4   5   3   4   8   8   8   4
5   May 4   -1  6   4   4   9   5   4   6
7   Jul 4   -2  4   4   2   6   6   9   3

我创建了列索引

conshead$b=(match(conshead[,conshead$monthabb],colnames(conshead[,24:31]))+23)

无法继续进行。请分享一个更好的逻辑。

【问题讨论】:

    标签: r dataframe multiple-columns


    【解决方案1】:

    这是tidyverse 的选项。创建一个序列列,rownames_to_columngather 数据集为 'long' 格式,按序列 ('rn') 分组后,slice 'abb' 等于 'key' 的行,@ 987654325@ 通过取逻辑表达式的sum (val[-1] > first(val)) 即计算有多少值大于发生匹配的第一个元素并将其绑定为原始数据集中的列 ('df1')

    library(tidyverse)
    rownames_to_column(df1, 'rn') %>% 
         gather(key, val, Apr:Nov) %>%
         group_by(rn) %>% 
         slice((which(abb == key) ): n()) %>% 
         summarise(Count = sum(val[-1] > first(val))) %>% 
         arrange(as.integer(rn)) %>% 
         pull(Count) %>% 
         bind_cols(df1, Count = .)
    #   mon abb Apr May Jun Jul Aug Sep Oct Nov Count
    #1    5 May   2   4   2   5   0   0   7   0     2
    #2    5 May   6   5   1   1   3   0   6   4     1
    #3    5 May   3   1   0   1   1   2   8   8     3
    #4    7 Jul   5   4   1   0   0   0   9   1     2
    #5    7 Jul   3   3   4   3   4   4   9   9     4
    #6    7 Jul   4   2   3   3   1   2   7   4     2
    #7    7 Jul   4   1   4   2   3   5   4   3     4
    #8    6 Jun   4   0   4   3   3   6   5   5     3
    #9    7 Jul   4   4   5   3   4   8   8   8     4
    #10   5 May   4  -1   6   4   4   9   5   4     6
    #11   7 Jul   4  -2   4   4   2   6   6   9     3
    

    base R 将使用行/列索引来提取元素,然后创建一个逻辑矩阵来获取 rowSums

    #column index position where the match occurs with 'abb' column and column names
    i1 <- match(df1$abb, names(df1)[-(1:2)])
    #replace elements in each row before the match to NA
    m1 <- replace(df1[-(1:2)], cbind(rep(seq_along(i1), i1-1), sequence(i1-1)), NA)
    #extract the elements where the match occured and compare it with 'm1'
    df1$Count <- rowSums(m1 > df1[-(1:2)][cbind(1:nrow(df1), i1)], na.rm = TRUE)
    df1$Count
    #[1] 2 1 3 2 4 2 4 3 4 6 3
    

    【讨论】:

    • @AlbertRajan 你有没有加载dplyr, tidyr` 包
    • 你可以做df1 &lt;- rownames_to_column(df1, 'rn') %&gt;% gather(key, val, Apr:Nov) %&gt;% group_by(rn) %&gt;% slice((which(abb == key) ): n()) %&gt;% summarise(Count = sum(val[-1] &gt; first(val))) %&gt;% arrange(as.integer(rn)) %&gt;% pull(Count) %&gt;% bind_cols(df1, Count = .)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-04
    • 2011-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-03
    • 1970-01-01
    相关资源
    最近更新 更多