在 R 中的数据框上使用 approx 保留类型因子的列

keep columns of type factor using approx on a data frame in R

我有一个包含很多列的大数据框。其中一些是 double 类型,另一些是 factor 类型。我通过使用 approx 函数和方法 = "constant" 添加一个新列 "time" 来重新采样数据帧。之后,所有因子列都更改为双精度。

例如:

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))

即使我使用函数 approx,是否可以将因子列保持为因子,将 double 类型的列保持为双精度?

编辑: 我发现在因子上使用 approx 函数没有意义并且不想使用 na.rm = TRUE 因为我在某些列中有很多 NA,如果我用以前的值替换它们关于分布等的原始数据将有很大的不同。是否有替代解决方案来为非因子列执行近似函数,然后将其与原始因子列合并?我认为不使用先验值填充因子列并且仅使用与重采样时间相关的原始值(如 0.1、0.2 等)是有意义的。之后它可以合并。

我只是对如何将 df1 和 df2 与重新采样的时间频率相结合感到困惑,因此我的分布和线图与原始数据完全不同。我想达到的最终目标是在特定时间范围内对某些特定因素进行一些比较。所以我不能比较不同的变量,因为另一个可能是 NA。

所以,我不清楚您要在这里完成的工作的总体情况,这很好;我很了解具体问题。但是,我相信您 真的非常确定 这是个好主意——从表面上看,我会非常担心通过 approx() 作用于因子变量的基础整数(完全没有意义)。在我看来,可能有一种 "better"(即不那么笨拙)的方法来完成这项工作,但我无法帮助你做到这一点,因为我不清楚你的总体目标。

也就是说,这是一个可能的路线图,可以使用 base R:

来完成您想要的事情
  • 确定哪些变量应该是因子
  • approxData 中,将这些变量转换回因子类型
  • 根据 df
  • 中的相应值重新映射新因子变量的 levels

代码,扩展了一个额外的因子列(以验证它在具有多个因子变量的情况下是否正常运行):

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 的值从 df1df2 复制而来,在其他地方都是 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() 是在此上下文中一次合并三个(或更多)数据框的快捷方式。请注意,如果任何合并的数据帧具有共同的变量,您会得到一些意想不到的行为,而在本例中它们没有。