我有一个数据集,其中包含我想要合并的列:
library(data.table)
DF <- as.data.table(list(ID = c(1,2,3,4,5), Product = c('Y', NA, NA, 'Z', NA), Type = c(NA, 'D', 'G', NA, NA)))
DF
ID Product Type
1 Y NA
2 NA D
3 NA G
4 Z NA
5 NA NA
我希望看起来像这样:
DF
ID Product Type Category
1 Y NA Y
2 NA D D
3 NA G G
4 Z NA Z
5 NA NA NA
我的代码是:
DF[,Category := na.omit(c(Product,Type)), by = ID][,c("Product","Type"):=NULL]
我遇到的问题是,当Category
和NA
都是Product
时,我希望Type
为NA
。另外,我不知道我的代码是否有效,因为我的数据集有超过200,000行。
答案 0 :(得分:5)
DF[ , Category := ifelse(is.na(Product), Type, Product)]
# ID Product Type Category
#1: 1 Y NA Y
#2: 2 NA D D
#3: 3 NA G G
#4: 4 Z NA Z
#5: 5 NA NA NA
如果Product
和Type
都有值,则假设您需要Product
中的Category
答案 1 :(得分:4)
我们可以在两个作业中执行此操作,并避免ifelse
因为作业(:=
)更快更有效。
DF[, Category := Product][is.na(Product), Category := Type][]
# ID Product Type Category
#1: 1 Y NA Y
#2: 2 NA D D
#3: 3 NA G G
#4: 4 Z NA Z
#5: 5 NA NA NA
或者,如果我们假设产品/类型每行最多只有1个非NA值,则可以使用pmax
。
DF[, Category := pmax(Product, Type, na.rm = TRUE)][]
# ID Product Type Category
#1: 1 Y NA Y
#2: 2 NA D D
#3: 3 NA G G
#4: 4 Z NA Z
#5: 5 NA NA NA
DF1 <- DF[rep(1:nrow(DF), 1e6)]
DF2 <- copy(DF1)
DF3 <- copy(DF1)
system.time(DF1[, Category := Product][is.na(Product), Category := Type])
# user system elapsed
# 0.16 0.06 0.17
system.time(DF2[ , Category := ifelse(is.na(Product), Type, Product)])
# user system elapsed
# 1.35 0.19 1.53
system.time(DF3[ ,Category := pmax(Product, Type, na.rm = TRUE)])
# user system elapsed
# 0.04 0.02 0.06
编辑:更新了基准,它清楚地显示了我的帖子中提到的两种方法都是有效的。