根据另一行是否唯一选择一行的值

时间:2019-07-15 17:23:20

标签: r

我需要在数据中创建一个新列,如果“ id”仅出现一次,则该列等于“投标”值,如果没有,则等于“批次”值。我无法通过有关NA的任何方法来完成此操作,因为数据不完整,并且那里有很多NA。我的想法是这样做,如果'id'是唯一的,则选择

df <- data.frame('id'=c(1,1,2,3,3,4), 
                 'lot'=c(10,20,NA,40,50,NA), 'tender'=c(30,30,30,90,90,40))

A期望输出为:

data.frame('id'=c(1,1,2,3,3,4), 'lot'=c(10,20,NA,40,50,NA), 
           'tender'=c(30,30,30,90,90,40),'price'=c(10,20,30,40,50,40))

感谢您的帮助

3 个答案:

答案 0 :(得分:3)

我们可以这样做:

df$price <- apply(df, 1, function(x) min(x["lot"], x["tender"], na.rm = TRUE))

或者在dplyr解决方案中是:

library(dplyr)
df %>% 
  rowwise() %>% 
  mutate(price = min(lot, tender, na.rm = TRUE))
# # A tibble: 6 x 4
# # Groups:   id [4]
#      id   lot tender price
#   <dbl> <dbl>  <dbl> <dbl>
# 1     1    10     30    10
# 2     1    20     30    20
# 3     2    NA     30    30
# 4     3    40     90    40
# 5     3    50     90    50
# 6     4    NA     40    40

答案 1 :(得分:2)

根据条件,我们可以按case_when进行分组

library(dplyr)
df %>% 
  group_by(id) %>%
  mutate(price = case_when(n() ==1 & is.na(lot) ~ tender, TRUE ~ lot))

在OP的当前示例中,coalesce也可以工作

df %>%
   mutate(price = coalesce(lot, tender))

答案 2 :(得分:1)

基于此描述,您可以在带有data.table的组大小上使用if语句

  

我需要在我的数据中创建一个新列,它等于   如果“ id”仅出现一次,则“投标”值   值,以防万一。

library(data.table)
setDT(df)

df[, price := if(.N == 1) tender else lot, by = id]
#    id lot tender price
# 1:  1  10     30    10
# 2:  1  20     30    20
# 3:  2  NA     30    30
# 4:  3  40     90    40
# 5:  3  50     90    50
# 6:  4  NA     40    40