【问题标题】:Select first observed data and utilize mutate选择第一个观察到的数据并利用 mutate
【发布时间】:2015-06-11 17:02:36
【问题描述】:

我的数据遇到了问题,我想为每个人id 获取第一个观察到的ob 得分score,然后从最后观察到的score 中减去它。

要求第一次观察减去最后一次观察的问题是,有时第一次观察数据会丢失。

是否需要询问每个人的第一个观察分数,从而跳过任何缺失的数据?

我构建了下面的 df 来说明我的问题。

help <- data.frame(id = c(5,5,5,5,5,12,12,12,17,17,20,20,20),
                   ob = c(1,2,3,4,5,1,2,3,1,2,1,2,3),
                   score = c(NA, 2, 3, 4, 3, 7, 3, 4, 3, 4, NA, 1, 4))

   id ob score
1   5  1    NA
2   5  2     2
3   5  3     3
4   5  4     4
5   5  5     3
6  12  1     7
7  12  2     3
8  12  3     4
9  17  1     3
10 17  2     4
11 20  1    NA
12 20  2     1
13 20  3     4

而我希望运行的是可以给我的代码......

   id ob score  es
1   5  1    NA  -1
2   5  2     2  -1
3   5  3     3  -1
4   5  4     4  -1
5   5  5     3  -1
6  12  1     7   3
7  12  2     3   3
8  12  3     4   3
9  17  1     3  -1
10 17  2     4  -1
11 20  1    NA  -3
12 20  2     1  -3
13 20  3     4  -3

我正在尝试使用 dplyr,并且我了解“group_by”命令的使用,但是,不确定如何“选择”仅首先观察到的分数,然后变异以创建 es

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    我会使用first()last()dplyr 函数)和na.omit()(来自默认统计包。

    首先,我会确保您的分数列是具有正确 NA 值的数字列(而不是您示例中的字符串)

    help <- data.frame(id = c(5,5,5,5,5,12,12,12,17,17,20,20,20),
           ob = c(1,2,3,4,5,1,2,3,1,2,1,2,3),
           score = c(NA, 2, 3, 4, 3, 7, 3, 4, 3, 4, NA, 1, 4))
    

    那你就可以了

    library(dplyr)
    help %>% group_by(id) %>% arrange(ob) %>% 
        mutate(es=first(na.omit(score)-last(na.omit(score))))
    

    【讨论】:

    • 当我在我的实际数据上运行此代码时,我得到一个错误 --> “错误:不知道如何为类数字对象生成默认值”。变量是数字的,并且有相当数量的 NA,例如一些 id 除了 NA 之外什么都没有,而另一些则没有。有什么想法吗?
    • 如果你只有 NA 值,你想返回什么?如果您的示例数据包含此场景以及所需的输出,那就太好了。
    • 同意。所以问题在于有 3 个不同的 score 变量,每个 id 都有三个变量之一的分数。我以为我可以只为每个人运行代码,但是如果 group_by 中的 id 没有任何得分数据,则会弹出错误消息......可能是因为 na.omit 取出所有数据并在那里没有什么可减去的。
    • 如果整个组只包含NAs,您可以告诉first()last() 如何使用default= 参数来处理它,例如:es = first(na.omit(score), default=NA)
    • @MrFlick - 此代码不再有效,我很难弄清楚。我猜它与 dplyr 中的更新有关(现在在 0.5.0 版上)。运行上述代码时,我收到错误“错误:不支持的向量类型语言”。有什么想法吗?数据的结构都是整数或数字。
    【解决方案2】:
    library(dplyr)
    
    temp <- help %>% group_by(id) %>% 
         arrange(ob) %>%
         filter(!is.na(score)) %>% 
         mutate(es = first(score) - last(score)) %>%
         select(id, es) %>%
         distinct()
    
    help %>% left_join(temp)
    

    【讨论】:

      【解决方案3】:

      这个解决方案有点冗长,只有 b/c 它依赖于几个辅助函数 FIRSTLAST

      # The position (indicator) of the first value that evaluates to TRUE.
      LAST  <-  function (x, none = NA) {
          out <- FIRST(reverse(x), none = none)
          if (identical(none, out)) {
              return(none)
          }
          else {
              return(length(x) - out + 1)
          }
      }
      # The position (indicator) of the last value that evaluates to TRUE.
      FIRST  <-  function (x, none = NA) 
      {
          x[is.na(x)] <- FALSE
          if (any(x)) 
              return(which.max(x))
          else return(none)
      }
      
      # returns the difference between the first and last non-missing values
      diff2  <-  function(x)
          x[LAST(!is.na(x))] - x[FIRST(!is.na(x))]
      
      
      library(dplyr)
      help %>% 
          group_by(id) %>% 
          arrange(ob) %>% 
              summarise(diff = diff2(score))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多