我的问题建立在this问题的数据表答案的基础上(完全披露:我也提出了相关问题)。我也从其他SO问题和答案中受益匪浅,我花了很多时间阅读有关功能的内容,但还没有成功。
我有几行代码可以很好地用于我的目的,但我必须为5个不同的变量运行相同的代码。因此,我想编写一个函数来提高这个过程的效率。
示例数据框:
id <- c(1, 1, 1, 1, 2, 3, 4, 4, 5, 5, 5)
bmi <- c(18, 22, 23, 23, 20, 38, 30, 31, 21, 22, 24)
other_data <- c("north_africa", "north_africa", "north_africa", "north_africa", "western_europe", "south_america", "eastern_europe", "eastern_europe", "ss_africa", "ss_africa", "ss_africa")
other_data2 <- c(0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0)
big_df <- data.frame(id, bmi, other_data, other_data2)
#first make a data table with just the id and bmi columns
bmi_dt <- as.data.table(big_df[c(1, 2)])
#restructure data so that each ID only has one row
bmi_dt <- bmi_dt[, c(bmi_new = paste(bmi, collapse = "; "), .SD), by = id][!duplicated(bmi_dt$id)]
#split the strings of multiple numbers into 4 new cols
bmi_dt[, c("bmi1", "bmi2", "bmi3", "bmi4") := tstrsplit(as.character(bmi_new), "; ", fixed=TRUE)]
#make columns numeric
bmi_dt <- bmi_dt[, lapply(.SD, as.numeric), by = id]
#function to replace NA with 0 in a data table
func_na <- function(DT) {
for (i in names(DT))
DT[is.na(get(i)), i:=0, with=FALSE]
}
func_na(bmi_dt)
最后一部分,这个功能,是由Matt Dowle在this SO回答中写的。
我一直试图通过从小开始为这个序列创建一个整体函数,但即使是最基本的部分也无法正常工作。这是我失败的尝试之一:
big_func <- function(DT, old_col, id_col) {
DT <- DT[, c(new_col = paste(old_col, collapse = "; "), .SD), by = id_col][!duplicated(id_col)]
DT
}
test <- big_func(bmi_dt, bmi, id)
我真的很想明白:
a)为什么我的尝试不适用于第一部分?
b)为所有这些创建一个大函数是否有意义?
c)如果是这样,我该怎么做?
修改:我现在看到有关重塑数据表here的问题。我认为我关于编写函数的问题是一个单独的问题。
答案 0 :(得分:1)
您可以通过以下方式避免所有这些粘贴/拆分/转换/替换:
library(data.table)
big_dt <- as.data.table(big_df)
big_dt[, id_bmi := 1:.N, by = id]
dcast(big_dt[, list(id, id_bmi, bmi)], id ~ id_bmi, value.var = 'bmi', fill = 0)