我有一个大的数据框,里面有很多列。其中一些列的类型是double,另一些列的类型是factor。我通过添加一个新的列 "time "来重新取样数据框,并使用约函数和方法="constant"。之后,所有的因子列都改为双数。
比如说
So my idea looks like this:
time = seq(1, 6, by = 0.1)
df1 <- data.frame(ecuTime = c(2, 4, 6), a = as.factor(c("male", "female",
"male")), b = c(1, 3, 5))
df2 <- data.frame(ecuTime = c(1, 3.2, 3.4, 6), c = as.factor(c("car", "car",
"bike", "car")), d = c(2, 3, 5, 6))
dfComb <- merge(df1, df2, by = "ecuTime", all = TRUE)
approxData <- cbind.data.frame(time, sapply(dfComb[, names(dfComb)],
function(y, x, nout)
approx(x, y, nout, method = "constant", na.rm = FALSE)$y,
x = dfComb$ecuTime, nout = time))
是否可以将因子列保持为因子,而将类型为double的列保持为double,即使我使用函数approx?
编辑:我发现在因子上使用近似函数没有意义,而且不想使用na.rm = TRUE,因为我在一些列中有很多NA,如果我用以前的值替换它们,会对原始数据的分布等产生很大的影响。是否有其他的解决方案,只对非因子列进行约函数,然后与原始因子列合并?我觉得有道理的是,不要用先验值填充因子列,只用与重采样时间相关的原始值,比如0.1,0.2等。之后就可以合并了。
我只是很困惑,如何将df1和df2与重采样的时间频率合并,使我的分布和线图与原始数据完全不同。我最终想达到的目标是在特定的时间范围内对一些特定的因素进行一些比较。所以我不能比较不同的变量,因为另一个变量可能是NA。
所以,我不清楚你在这里想做什么的大局,这很好;我对具体问题理解得很清楚。然而,我相信你是 真的 这是个好主意 -- 从表面上看,我很担心通过以下方法来做类似于算术的事情 approx()
的函数(这些函数完全没有意义)。在我看来,可能有一个 "更好的"(即不那么黑客化)的方法来完成这个任务,但我无法帮助你做到这一点,因为我不清楚你的总体目标。
话虽如此,这里有一个可能的路线图来实现你的愿望,使用 base
R:
approxData
,将这些变量转换回因子类型levels
新的因子变量的数值,基于来自于 df
代码,扩展了一个额外的因子列(以验证在有多个因子变量的情况下是否能正常运行)。
time = 1:6
df <- data.frame(ecuTime = c(2, 4, 6), a = as.factor(c("male", "female",
"male")), b = c(1, 3, 5),
c = c("blue", "blue", "yellow"))
str(df)
approxData <- cbind.data.frame(time, sapply(df[, names(df)],
function(y, x, nout)
approx(x, y, nout, method = "constant")$y,
x = df$ecuTime, nout = time))
str(approxData)
factor_vars <- names(df[, sapply(df, is.factor)])
approxData[, factor_vars] <-
lapply(factor_vars, function(x) {
approxData[[x]] <- factor(approxData[[x]]);
levels(approxData[[x]]) <- levels(df[[x]]);
approxData[[x]]
})
str(approxData)
对于编辑过的问题:这里有一些代码可以生成一个新的数据框架。dfComb_resample
. 该数据帧有一个扩展的 ecuTime
变量,值为 a, b, c, d
抄自 df1
和 df2
适当时,以及 NA
其他地方的价值。如果我错过了你想要的东西,请告诉我)。
time = seq(1, 6, by = 0.1)
df1 <- data.frame(ecuTime = c(2, 4, 6), a = as.factor(c("male", "female",
"male")), b = c(1, 3, 5))
df2 <- data.frame(ecuTime = c(1, 3.2, 3.4, 6), c = as.factor(c("car", "car",
"bike", "car")), d = c(2, 3, 5, 6))
dfComb_resample <-
Reduce(function(x, y) merge(x=x, y=y, by = "ecuTime", all = TRUE),
list(data.frame(ecuTime = time), df1, df2))
它是如何工作的。Reduce()
是在这种情况下一次合并三个(或更多)数据帧的快捷方式。请注意,如果任何一个合并的数据帧有共同的变量,你会得到一些意想不到的行为,而在这个例子中它们没有。