【问题标题】:create new column (with outcome min or NA) from multiple selected columns从多个选定的列创建新列(带有结果最小值或 NA)
【发布时间】:2020-08-26 19:44:07
【问题描述】:

我的数据有很多列和主题,但为了更简单地说明,假设我有 7 个主题,有 3 个变量/列,称为 x1、x2 和 x3(值范围从 1 到 3 和 NAs)。在我想要的分析中,重要的是我实际上调用了我想要使用的列(因为我不能只在分析中使用整个数据框,因为那里有更多变量/列)

>data <- data.frame(‘id’=c(1,2,3,4,5,6,7), ‘x1’=c(1,2,2,NA,3,3,1), ‘x2’=c(NA,3,1,NA,2,3,2), ‘x3’=c(NA,2,NA,NA,3,NA,1)
    id  x1  x2  x3
    1   1   NA  NA
    2   2   3   2
    3   2   1   NA
    4   NA  NA  NA
    5   3   2   NA
    6   3   3   NA
    7   1   2   1

x1 x2 和 x3 的类是数字的。 除此之外,我想创建一个名为“x4”的变量/列: - 给了我最少的行数 x1、x2 和 x3。

-如果在 x1,x2,x3 的行中存在 NA,则应忽略 NA。

-但是,如果他们都是 NA,我希望结果是 NA。 (不是 Inf,这就是它现在对我的代码所做的)

-如果有两个相同的最小数字,则只显示这两个中的任何一个。像这样:

>data <- data.frame(‘id’=c(1,2,3,4,5,6,7), ‘x1’=c(1,2,2,NA,3,3,1), ‘x2’=c(NA,3,1,NA,2,3,2), ‘x3’=c(NA,2,NA,NA,3,NA,1), ‘x4’=c(1,2,1,NA,2,3,1)
    id  x1  x2  x3  x4
    1   1   NA  NA  1
    2   2   3   2   2
    3   2   1   NA  1
    4   NA  NA  NA  NA  
    5   3   2   NA  2
    6   3   3   NA  3
    7   1   2   1   1

我设法找到了一个非常相似的问题,而且我基本上可以让它工作:min for each row with dataframe in R

data$x4

我现在遇到的问题是,对于所有 NA(所以 id 编号为 4),我的结果不是 NA,而是“Inf”。

问题 1:我怎样才能使它成为 NA 而不是 Inf?之后我当然可以这样做:

is.na(data$x4)

但我想知道是否有一种很好的方法可以在之前的代码中/在之前的代码中做到这一点?

另外,除了使用 sapply 和内部 FUNction min 之外,我还想尝试以如下方式使其与代码一起使用:问题 2: 正在使用以下其他代码?

data$x4

因为这个 x4 每次都会得到结果“1”。我猜它只是显示了整列的最低数字(1)?我不明白为什么。我已经在使用 ',1' 但没有帮助。

我希望有人可以帮助我(r 和 stackoverflow 新手),谢谢!

【问题讨论】:

    标签: r apply min sapply inf


    【解决方案1】:

    您可以在调用min 之前测试是否全部为NA,例如:

    apply(data[, c("x1","x2","x3")], 1, function(x)
      if(all(is.na(x))) NA else min(x, na.rm=TRUE))
    #[1]  1  2  1 NA  2  3  1
    

    min(data[, c("x1","x2","x3")],1 , na.rm = TRUE) 为您提供1data[, c("x1","x2","x3")] 中的最小值。

    【讨论】:

    • 感谢您的回答!我了解您对问题 1 的回答,谢谢!但是对于问题 2,我没有看到我的代码的改进版本?我想你用的一样吗?所以我认为我的代码所做的是查看整列的最小值,但我也希望它查看每行的最小值。我无法在我的代码中更改它。附言,抱歉我的回复晚了
    • 这一行可以获得最小值。例如。第 1 行 min(data[1, c("x1","x2","x3")], na.rm = TRUE) 或第 2 行 min(data[2, c("x1","x2","x3")], na.rm = TRUE)
    • 感谢您的回复!是的,可以,但是代码是否可以自动对所有七行执行此操作并创建我想要的 x4 列?我试过 min(data[1:7, c("x1","x2","x3")], na.rm = TRUE) ,但它只给出了七行之一的相同最小值。所以我的结果又是全部 1 1 1 1 1 1 1。
    • 在这种情况下使用apply 遍历每一行。
    【解决方案2】:

    您正在寻找pmin 函数,它返回输入值的(常规或并行)最小值。以下是使用 pmin 的两种方法:

    df$minIget <- do.call(pmin, c(df[,-1], na.rm = TRUE)) # Approch1: using do.call
    
    df %>% rowwise() %>% mutate(minIget = pmin(x1, x2,x3,na.rm = T))# Approch2: using tidyverse. 
    

    输出:

     A tibble: 7 x 5
    # Rowwise: 
         id    x1    x2    x3 minIget
      <dbl> <dbl> <dbl> <dbl>   <dbl>
    1     1     1    NA    NA       1
    2     2     2     3     2       2
    3     3     2     1    NA       1
    4     4    NA    NA    NA      NA
    5     5     3     2     3       2
    6     6     3     3    NA       3
    7     7     1     2     1       1
    

    【讨论】:

    • 感谢您的回答!关于方法 1. 我得到错误不正确的维度数。我根据您的代码尝试了这些代码:df$minIget &lt;- do.call(pmin, c("x1","x2","x3"[,-1], na.rm = TRUE)) 我也尝试了这个并得到了同样的错误:df$minIget &lt;- do.call(pmin, c(data$x1,data$x2, data$x3 [,-1], na.rm = TRUE))
    • @RelcioR 您错误地引用了列。变量的选择可以通过索引或列名来完成。在方法 1 中。根据我的回答,我使用索引传递, df[,-1] 指的是除最后一列之外的所有列。在方法 2 中,我使用了列名。 Refer 。因此,您必须按照我的答案中给出的那样运行它,它才能正常运行
    • 感谢您回复我并帮助我理解它:) 此外,关于引用的链接对我非常有用(我仍然是初学者)。谢谢!
    • 没问题,这就是 SO 的目的,通过互相帮助来学习。此外,如果其他 SO 成员回答了他的问题,那么问题发布者最好在所有解决方案中投票并选择一个答案。请参阅 thisthis 。您可以为多个答案投票,但选定的答案只能是一个,您将在其中单击标记。
    猜你喜欢
    • 2014-01-26
    • 2021-08-25
    • 2016-11-17
    • 2020-12-27
    • 2020-12-16
    • 2015-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多