【问题标题】:Getting all NAs in a new column [Mutate]在新列中获取所有 NA [变异]
【发布时间】:2020-12-04 10:07:20
【问题描述】:

我需要创建一个新列,它是两个或三个其他列的函数,其中一个包含一些缺失数据 (NA)。但是,当我使用dplyrmutate 函数时,新列包含所有NA。

请看下面的例子:

rand_df <- data.frame(replicate(10,sample(0:10,200,rep=TRUE))) # random df
names(rand_df) <- letters[seq(from=1, to=10)]  #renaming header
rand_df$c[2:20] <- NA  # introducing NAs
head(rand_df)

 a b  c d  e f  g h i j
1  3 1  8 2  4 3  1 9 2 9
2  6 1 NA 1  2 8  8 6 0 9
3  5 7 NA 2  4 1  7 7 3 0
4 10 8 NA 6  6 7  0 2 2 0
5  4 1 NA 9  3 8  2 2 5 2
6 10 8 NA 3 10 2 10 4 5 5

尝试创建一个新列

rand_df <- rand_df %>% mutate(k = 141 * min((c/88.42), 1))

head(rand_df):

a b  c d  e f  g h i j  k
1  3 1  8 2  4 3  1 9 2 9 NA
2  6 1 NA 1  2 8  8 6 0 9 NA
3  5 7 NA 2  4 1  7 7 3 0 NA
4 10 8 NA 6  6 7  0 2 2 0 NA
5  4 1 NA 9  3 8  2 2 5 2 NA
6 10 8 NA 3 10 2 10 4 5 5 NA

我知道我可以简单地使用 for 循环逐行循环并跳过包含 NA 的行,但我想有更好的方法来做到这一点。

【问题讨论】:

    标签: r dplyr na missing-data


    【解决方案1】:

    你可以使用 pmin()。

        library(dplyr)
        rand_df <- data.frame(replicate(10,sample(0:10,200,rep=TRUE))) # random df
        names(rand_df) <- letters[seq(from=1, to=10)]  #renaming header
        rand_df$c[2:20] <- NA  # introducing NAs
        head(rand_df)
        #>   a b  c d  e  f g  h  i  j
        #> 1 4 9  9 6 10  2 1 10 10 10
        #> 2 7 3 NA 2  5  9 1  2 10  6
        #> 3 0 3 NA 4  5  6 1  0 10  6
        #> 4 0 7 NA 5  3  6 6  9  4  7
        #> 5 4 4 NA 5  4 10 8  5  6  0
        #> 6 1 3 NA 3  0 10 1  3  7  4
    
    
        rand_df <- rand_df %>% mutate(k = 141 * pmin((c/88.42), 1))
        head(rand_df)
        #>   a b  c d  e  f g  h  i  j        k
        #> 1 4 9  9 6 10  2 1 10 10 10 14.35196
        #> 2 7 3 NA 2  5  9 1  2 10  6       NA
        #> 3 0 3 NA 4  5  6 1  0 10  6       NA
        #> 4 0 7 NA 5  3  6 6  9  4  7       NA
        #> 5 4 4 NA 5  4 10 8  5  6  0       NA
        #> 6 1 3 NA 3  0 10 1  3  7  4       NA
    
    <sup>Created on 2020-08-17 by the [reprex package](https://reprex.tidyverse.org) (v0.3.0)</sup>
    
    

    【讨论】:

    • 非常感谢。我已编辑问题以使其更清晰。
    • @janderkran,我编辑了您的答案,使用 OP 提供的新数据集看起来是正确的。对于 OP,问题 + 关联数据越精确,获得快速答案的机会就越大。
    【解决方案2】:

    以下代码行失败,因为min((c/88.42),1)) 没有根据每一行进行计算,而是使用整个列,所以你只是重复了相同的值:

    rand_df <- rand_df %>% mutate(k = 141 * min((c/88.42), 1))
    

    这很好地说明了这种行为:

    rand_df %>% mutate(k = min(f), k1 = max(f))) 
    

    有不同的方法来解决这个问题,但一种是将行号添加为列,然后使用group_by:

    rand_df  %>% 
      mutate(row = row_number()) %>% 
      group_by(row) %>% 
      mutate(k = 141 * min((c/88.42), 1))
    

    【讨论】:

    • dplyr 的新版本上,rowwise() 无需借助任何技巧即可做到这一点。
    • 我以为他们已经放弃了?不管怎样,你每天都会学到新东西……
    • 我认为他们几年前试图摆脱它,但它得到了一些新的喜爱(而且可能不容易做得更好),所以它实际上是在 dplyr 1.0 中推广的。查看最近的意见:tidyverse.org/blog/2020/04/dplyr-1-0-0-rowwise
    • @RobertWilson 非常感谢您的澄清。我的实际目标是简单地找到最小 b/w c/88.42 和 1,我认为 pmin 就是这样做的。我之前不明白@janderkran 的回答,但我现在明白了。
    【解决方案3】:

    似乎您在 ifelse() 函数中添加了额外的参数。我的意思是 33.5 在这里是不必要的。

    还有,下次请一定要好好提问(根据本指南How to make a great R reproducible example

    【讨论】:

    • 非常感谢。我用一个可重复的例子编辑了这个问题。我希望现在更清楚了。
    猜你喜欢
    • 2021-12-18
    • 2018-02-21
    • 2020-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-12
    • 2015-01-04
    • 1970-01-01
    相关资源
    最近更新 更多