【问题标题】:Subsetting a dataframe to exclude values in the same row as NA对数据框进行子集化以排除与 NA 在同一行中的值
【发布时间】:2019-01-12 21:31:00
【问题描述】:

我有一个名为“数据”的数据框。其中一列称为“reward”,另一列称为“X.targetResp”。我想创建一个名为“reward”的新数据框,它包含“data”中“reward”列中的所有值。但是,我想排除与“data”的“X.targetResp”列中的 NA 值位于同一行的“reward”列的值。

我尝试了以下方法:

reward <- data$reward %in% filter(!is.na(data$X.targetResp))
reward <- subset(data, reward, !(X.targetResp=="NA"))
reward <- subset(data, reward, !is.na(X.targetResp))

...但我得到了他们每个人的错误。

感谢您的意见!

【问题讨论】:

    标签: r select subset na


    【解决方案1】:

    dplyr中,您可以使用filter!is.na()过滤掉X.targetResp中的NA,然后使用select函数选择reward列。

    library(dplyr)
    
    # Create example data frame
    dat <- data_frame(reward = 1:5,
                      X.targetResp = c(2, 4, NA, NA, 10))
    
    # Print the data frame
    dat
    # # A tibble: 5 x 2
    #   reward X.targetResp
    #    <int>        <dbl>
    # 1      1            2
    # 2      2            4
    # 3      3           NA
    # 4      4           NA
    # 5      5           10
    
    # Use the filter function
    reward <- dat %>%
      filter(!is.na(X.targetResp)) %>%
      select(reward)
    reward
    # # A tibble: 3 x 1
    # reward
    #    <int>
    # 1      1
    # 2      2
    # 3      5
    

    这是一个具有类似逻辑的基本 R 解决方案。

    subset(dat, !is.na(X.targetResp), "reward")
    # A tibble: 3 x 1
    reward
    #    <int>
    # 1      1
    # 2      2
    # 3      5
    

    您还可以考虑在X.targetResp 上使用drop_na tidyr

    library(dplyr)
    library(tidyr)
    reward <- dat %>%
      drop_na(X.targetResp) %>%
      select(reward)
    reward
    # # A tibble: 3 x 1
    #   reward
    #    <int>
    # 1      1
    # 2      2
    # 3      5
    

    这是data.table 包的示例。

    library(data.table)
    
    setDT(dat)
    
    reward <- dat[!is.na(X.targetResp), .(reward)]
    reward
    #    reward
    # 1:      1
    # 2:      2
    # 3:      5
    

    【讨论】:

      【解决方案2】:

      您可以简单地使用na.omit,它旨在解决这个问题:

      # replicating the same example data frame given by @www
      data <- data.frame(
        reward = 1:5,
        X.targetResp = c(2, 4, NA, NA, 10)
      )
      
      # omitting the rows containing NAs
      reward <- na.omit(data)
      
      # resulting data frame with both columns
      reward
      #   reward X.targetResp
      # 1      1            2
      # 2      2            4
      # 5      5           10
      
      # you can easily extract the first column if necessary
      reward[1]
      #   reward
      # 1      1
      # 2      2
      # 5      5
      

      跟进@www 的评论:

      如果有其他列要避开:

      # omitting the rows where only X.targetResp is NA
      reward <- data[complete.cases(data["X.targetResp"]),  ]
      
      # resulting data frame with both columns
      reward
      #   reward X.targetResp
      # 1      1            2
      # 2      2            4
      # 5      5           10
      
      # you can easily extract the first column if necessary
      reward[1]
      #   reward
      # 1      1
      # 2      2
      # 5      5
      

      【讨论】:

      • na.omit 的问题是它可能会删除比预期更多的行,因为其他列也可能有 NA
      • @www;虽然问题只显示了两列,但我更新了我的答案以涵盖您使用complete.cases 提到的情况,这仍然是一个更简单的解决方案。
      • 这与哪个答案更简单无关。我只是想提醒您,这可能不是 OP 想要的。此外,没有证据表明 OP 的数据框只有两列。即使只有两列,如果reward 列中有NAna.omit 也会删除这些行。
      • 当然!有选择总是好的。感谢您指出可能的边缘情况。 complete.cases 现在涵盖了这些问题。干杯!
      猜你喜欢
      • 2013-04-19
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-12
      • 2013-03-17
      相关资源
      最近更新 更多