【问题标题】:in R - for all TRUE, are all subsequent cols TRUE?在 R - 对于所有 TRUE,所有后续 cols 都是 TRUE 吗?
【发布时间】:2020-01-13 23:37:23
【问题描述】:

在 R 中: 我有一个逻辑数据框,我想知道每一行的所有值为 TRUE 的值,其中所有后续列也是 TRUE,第一个 TRUE 出现在哪一列。

示例数据框:

T1<-c(TRUE, TRUE, TRUE, FALSE)
T2<- c(FALSE, TRUE, TRUE, FALSE)
T3<- c(FALSE, FALSE, TRUE, TRUE)
T4<- c(FALSE, TRUE, TRUE, TRUE)
test_df<- as.data.frame(cbind(T1,T2,T3,T4))
test_df

看起来像:

     T1      T2     T3      T4
1   TRUE    FALSE   FALSE   FALSE
2   TRUE    TRUE    FALSE   TRUE
3   TRUE    TRUE    TRUE    TRUE
4   FALSE   FALSE   TRUE    TRUE

由于我也想知道最后一列,所以需要在最后添加一个空列

test_df$null_col<-TRUE

看起来像:

    T1      T2      T3      T4      null_col
1   TRUE    FALSE   FALSE   FALSE   TRUE
2   TRUE    TRUE    FALSE   TRUE    TRUE
3   TRUE    TRUE    TRUE    TRUE    TRUE
4   FALSE   FALSE   TRUE    TRUE    TRUE

对于每一行,如果为真,并且所有后续列都为真,则返回该行的列名 我该如何处理?我的第一直觉是首先创建第二个逻辑数据框,这样第一个函数只有在所有后续(右侧的列)都为 TRUE 时才返回 TRUE,然后是第二个函数来查找每一行的列值:首先是第二个逻辑数据框

    T1      T2      T3      T4      
1   FALSE   FALSE   FALSE   FALSE   
2   FALSE   FALSE   FALSE   TRUE    
3   TRUE    TRUE    TRUE    TRUE    
4   FALSE   FALSE   TRUE    TRUE    

然后第二个函数为每一行返回一个 col 值,可以是命名列表,也可以是行号完整的数据框:

1     NA
2     T4
3     T1
4     T3

【问题讨论】:

  • 为什么第 2 行的预期结果是 NA 而不是 T4
  • 一个疏忽 SymbolixAU!在我的实际答案中不需要,但我认为在这个例子中很有帮助。为了清楚起见,我将进行编辑。

标签: r dataframe


【解决方案1】:

我们可以使用max.col 创建一个表达式来获取第一列的位置索引,该索引在每一行中为 TRUE。要纠正连续没有TRUEs 的情况,请使用rowSums 创建另一个表达式以更改为NA

 names(test_df)[max.col(test_df, 'first') * NA^(!rowSums(test_df))]

【讨论】:

  • 老实说,我从未尝试过NA^*anything*。有趣的技术。
【解决方案2】:

如果m 是下面显示的任何输出,那么我们可以使用以下方法计算所需的向量:

names(DF)[apply(m, 1, match, x = TRUE)]
## [1] NA   NA   "T1" "T3"

1) rollapply 使用末尾注释中可重复显示的数据转置它,然后为转置对象中的每一列将all 应用到最后的 4、3、2 和 1 位置使用rollappply。然后转回给出如下所示的矩阵。

library(zoo)

t(rollapply(t(DF), ncol(DF):1, all, align = "left"))
##    [,1]  [,2]  [,3]  [,4]
## 1 FALSE FALSE FALSE FALSE
## 2 FALSE FALSE FALSE FALSE
## 3  TRUE  TRUE  TRUE  TRUE
## 4 FALSE FALSE  TRUE  TRUE

2) cumprod 以相反的顺序将cumprod 应用到每一行,然后反向并将0/1 转换为FALSE/TRUE。显示返回的矩阵。这仅使用基础 R。

nc <- ncol(DF)
t(apply(DF[nc:1], 1, cumprod))[, nc:1] == 1
##      T1    T2    T3    T4
## 1 FALSE FALSE FALSE FALSE
## 2 FALSE FALSE FALSE FALSE
## 3  TRUE  TRUE  TRUE  TRUE
## 4 FALSE FALSE  TRUE  TRUE

3) ReduceDF 上将Reduce 与&amp; 一起使用,每行反转,然后反转。这仅使用基础 R。

nc <- ncol(DF)
do.call("cbind", Reduce(`&`, DF[nc:1], acc = TRUE))[, nc:1]
##       [,1]  [,2]  [,3]  [,4]
## [1,] FALSE FALSE FALSE FALSE
## [2,] FALSE FALSE FALSE FALSE
## [3,]  TRUE  TRUE  TRUE  TRUE
## [4,] FALSE FALSE  TRUE  TRUE

注意

假设可重现形式的输入DF 为:

Lines <- "T1      T2      T3      T4      
1   FALSE   FALSE   FALSE   FALSE   
2   FALSE   FALSE   FALSE   FALSE   
3   TRUE    TRUE    TRUE    TRUE    
4   FALSE   FALSE   TRUE    TRUE"
DF <- read.table(text = Lines)

【讨论】:

    【解决方案3】:

    这是一种 方法,可根据 cmets 提供预期结果:

    test_df = data.frame(T1 = c(TRUE, TRUE, TRUE, FALSE),
                         T2 = c(FALSE, TRUE, TRUE, FALSE),
                         T3 = c(FALSE, FALSE, TRUE, TRUE),
                         T4 = c(FALSE, TRUE, TRUE, TRUE))
    
    test_df
    
    Rcpp::cppFunction('
    CharacterVector all_T(LogicalMatrix x) {
      CharacterVector col_names = colnames(x);
      CharacterVector out(x.nrow(), col_names(0));
    
      for (int i = 0; i < x.nrow(); i++){
        for (int j = x.ncol() - 1; j >= 0; j--){
          if (!x(i, j)){
            if (j == x.ncol() - 1) {
              out(i) = NA_STRING;
              } else {
                out(i) = col_names(j + 1);
              }
              break;
              }
          }
        }
      return(out);
    }
                      ')
    
    all_T(as.matrix(test_df))
    
    #[1] NA   "T4" "T1" "T3"
    

    如果您的规则是,如果它从 T -&gt; F -&gt; T 出发,那么这应该返回 NA 作为规则,这里是 @akrun 方法的派生:

    max_col = max.col(test_df, ties.method = 'first')
    new_col = names(test_df)[max_col] 
    new_col[length(test_df) + 1L - max_col != rowSums(test_df)] = NA_character_
    
    new_col
    #[1] NA   NA   "T1" "T3"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-14
      • 1970-01-01
      相关资源
      最近更新 更多