【问题标题】:How do I get a list of rows in a two column matrix that contain NA OR value < 0?如何获取包含 NA OR 值 < 0 的两列矩阵中的行列表?
【发布时间】:2018-06-04 13:52:19
【问题描述】:

我有一个 10 行的两列(用于测试)列数组(列)。例如。 列

       V243  V247
1   693   761
2  -733   791
3   665  -756
4    NA   892
5   821    NA
6   752   819
7  1092 -1137
8    NA   943
9   675   720
10  600   645

如果任何列在该行上包含 NA,我希望获得一个带有 T 或 F 的一列 10 行向量,如果任何列包含该行上的值

na_column neg_column
F            F
F            T
F            T
T            F
T            F
F            F
F            T
T            F
F            F
F            F

which(is.na(cols)) 返回 4、8、15。 它返回两列数组的索引列表,就好像它被平展成一行并连接了列一样。我希望它查看每一行,如果该行的任何列包含 NA,则返回该行号。我应该得到 4、5、8。

同样对于负值,我需要 2、3、7。 我不知道如何做到这一点。似乎在 R 中应该很容易。

【问题讨论】:

    标签: r


    【解决方案1】:

    试试这个选项:

    df <- data.frame(v1=c(1,NA,-3), v2=c(4,5,NA))
    rowSums(!is.na(df)) < ncol(df)
    [1] FALSE  TRUE  TRUE
    
    as.logical(rowSums(df < 0, na.rm=TRUE))
    [1] FALSE FALSE  TRUE
    

    数据:

      v1 v2
    1  1  4
    2 NA  5
    3 -3 NA
    

    Demo

    【讨论】:

    • 不错。我完全忘记了 rowSums 中的 na.rm 参数。我最初的第一部分也是is.na(do.call(`+`, df))
    • 为什么不只是as.logical(rowSums(is.na(df)))在第一种情况下?
    • @Moody_Mudskipper 因为在第一种情况下它已经吐出了逻辑?在第二种情况下,您也不需要as.logical,如果您只是打算在某处使用结果,因为在 R 的大部分区域中,0/1 的行为与FALSE/TRUE 几乎相同。
    • 我明白为什么您在使用比较时不需要as.logical,但据我所知,与ncol(df) 的否定+比较是不必要的。
    • 为了给 OP 预期的输出,我建议 df$na_column &lt;- substr(as.logical(rowSums(is.na(df))),1,1)df$neg_column &lt;- substr(as.logical(rowSums(df &lt; 0, na.rm=TRUE)),1,1)
    【解决方案2】:
    df$na_column <- is.na(rowSums(df))
    df$neg_column <- apply(df, 1, function(r) any(r < 0, na.rm = T))
    
    df
    #    V243  V247 na_column neg_column
    # 1   693   761     FALSE      FALSE
    # 2  -733   791     FALSE       TRUE
    # 3   665  -756     FALSE       TRUE
    # 4    NA   892      TRUE      FALSE
    # 5   821    NA      TRUE      FALSE
    # 6   752   819     FALSE      FALSE
    # 7  1092 -1137     FALSE       TRUE
    # 8    NA   943      TRUE      FALSE
    # 9   675   720     FALSE      FALSE
    # 10  600   645     FALSE      FALSE
    

    【讨论】:

    • 获取第一列的另一种方法是na_column &lt;- apply(dat, 1, anyNA)
    【解决方案3】:

    anyallR 中的函数,可以满足您的需求。因此在R中很容易

    expl <- read.table(text="
              693   761
             -733   791
              665  -756
               NA   892
              821    NA
              752   819
             1092 -1137
               NA   943
              675   720
              600   645")
    
    apply(expl, 1, function(x) any(is.na(x)))
    apply(expl, 1, function(x) all(is.na(x)))
    

    【讨论】:

    • 这不会为负值产生所需的结果。 neg_column
    • 是的。扩展它很简单,但正如我现在所看到的,C.Braun 在我之前用基本相同的方法回答了 5 分钟,并且(s)他也已经做了负值部分。所以我赞成她/他的回答,而不是编辑我的。
    • transform(df, na_col=apply(df, 1, anyNA), neg_col=apply(df, 1, function(x) any(x&lt;0, na.rm=TRUE)))transform(df, na_col=apply(df, 1, anyNA), neg_col=apply(df&lt;0, 1, any, na.rm=TRUE))
    猜你喜欢
    • 1970-01-01
    • 2020-01-07
    • 1970-01-01
    • 1970-01-01
    • 2020-01-25
    • 2014-02-08
    • 2013-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多