我是R和data.table的新手,但我正在尝试折叠采用以下格式的客户数据集 - 尽管它扩展到90列:
frame <- data.frame(
customer_id = c(123, 123, 123),
time = c(1, 2, 3),
rec_type = c('contact', 'appointment', 'sale'),
variable_1 = c('Yes', NA, "Yes"),
variable_2 = c(NA, 'No', NA),
variable_3 = c(NA, NA, 'complete'),
variable_4 = NA, stringsAsFactors = FALSE)
customer_id time rec_type variable_1 variable_2 variable_3 variable_4
123 1 contact Yes NA NA NA
123 2 appointment NA No NA NA
123 3 sale Yes NA complete NA
之前我问过 - What's the best way to collapse sparse data into single rows in R? - 如何将每个客户的数据折叠成一行,并在data.table和dplyr中得到两个有用的答案。
但是,这些答案无法处理多个值,例如'rec_type'字段或者其值是同一个值variable_1的多个实例。
我想要提供一个跨列工作的函数,并返回一个行向量,其中每个字段是每个字段的单个值,如果所有列值都为空或者为“多个”,则为NA
在这种情况下:我的输出将是
customer_id time rec_type variable_1 variable_2 variable_3 variable_4
123 multiple multiple Yes No complete NA
我研究了如何计算各列的唯一值:
unique_values <- function(x){
uniques <- dt[contact_no == x,][,lapply(.SD, uniqueN)]
uniques
}
lapply(dt$contact_no, unique_values)
但无法使用如何使用uniques结果返回我想要的结果。
有人可以建议我可以使用的方法吗?
是否有更简单的方法来解决问题?
答案 0 :(得分:3)
这是一个data.table方法。
setDT(frame)[, lapply(.SD, function(x)
{x <- unique(x[!is.na(x)])
if(length(x) == 1) as.character(x)
else if(length(x) == 0) NA_character_
else "multiple"}),
by=customer_id]
我们的想法是使用lapply
将匿名函数应用于所有变量,并以返回所需结果的方式构造函数。此函数去除NA值和重复,然后检查结果向量的长度。每个的输出都被转换为一个字符,以符合另一个customer_id发生“多重”的可能性。
返回
customer_id time rec_type variable_1 variable_2 variable_3 variable_4
1: 123 multiple multiple Yes No complete NA