我正试图使用循环或应用家庭解决方案的下一个问题。我有几个数据帧,如:
df1 <- data.frame(a = c(1,2,3,NA,NA,NA,NA,NA,9,NA),b = c(1,2,3,4,NA,NA,NA,8,9,10),c = c(1,2,3,NA,NA,NA,7,8,NA,NA))
df2 <- data.frame(a = c(1,2,3,4,5,6,NA,NA,NA,10),b = c(1,2,3,4,NA,NA,NA,8,9,10),c = c(1,2,3,NA,NA,NA,7,8,NA,NA))
df5 <- data.frame(a = c(1,2,3,4,5,6,NA,NA,9,10),b = c(1,2,3,4,5,6,NA,8,9,10),c = c(1,2,3,NA,NA,NA,7,8,9,NA))
我想用na。大约用来填补一些NA的空白。我的想法是:
l <- c(1,2,5)
for (i in l){
df[[i]] <- df[[i]] %>% mutate(a = na.approx(a, na.rm = FALSE))
df[[i]] <- df[[i]] %>% mutate(b = na.approx(b, na.rm = FALSE))
df[[i]] <- df[[i]] %>% mutate(c = na.approx(c, na.rm = FALSE))
}
在这个例子中,我得到了以下错误:
Error in UseMethod("mutate") :
no applicable method for 'mutate' applied to an object of class "c('double', 'numeric')"
和我的实际数据,我得到这个错误:
Error in `vectbl_as_col_location2()`:
! Can't extract columns past the end.
i Location 13101 doesn't exist.
i There are only 16 columns.
,"13101";将是名为"df13101"的数据框架的一部分。
当我检查class of dataframes时,我得到
[1] "data.frame"
这里是但是我的实际数据帧是
[1] "grouped_df" "tbl_df" "tbl" "data.frame"
,当我检查每个变量的类型时,我想要改变的都是数字(示例和实数)。
我需要了解如何正确调用这些数据框架,以及由于数据类或mutate的使用而可能面临的问题。我试过用mapply,但我对R很陌生,我对整个应用程序家族几乎没有了解。
任何帮助将是伟大的,感谢阅读!
问题中的代码有这些问题:
df[[1]]
与df1
不相同。第一个是指df
的第一列(不存在),第二个是有效的输入。相反,如果e
是df1
等所在的环境,那么我们可以根据字符串"df1"
将df1
称为e[["df1"]]
。- 没有必要单独应用
na.approx
到每一列,因为na.approx
可以一次处理整个数字数据帧。 - 这对你来说可能是也可能不是问题,但请注意,代码覆盖
df1
等,所以如果你想在运行它后再次测试它,那么就有必要重新创建原始的df1
等。您可能希望使用如下面的第二种方法所示的列表。
下面我们假设输入数据帧位于全局环境中,即位于您的工作区中。(如果数据帧在当前而不是全局环境中,则将e <- ...
行替换为e <- environment()
行。如果数据帧仅定义并位于函数中,并且它们在同一函数中被引用,则会出现这种情况
e[[nm]]
是指环境e
中的对象,其名称由nm
变量中保存的字符串的值给出。然后我们将na.approx
应用于此并将其分配回来。注意,na.approx
在应用于data.frame时返回一个矩阵,因此我们在左侧使用[]将矩阵中的值插入到数据帧中。
library(zoo)
e <- .GlobalEnv
nms <- paste0("df", l)
for (nm in nms) e[[nm]][] <- na.approx(e[[nm]], na.rm = FALSE)
或者将数据帧放入命名列表L
L <- mget(nms) # nms defined above
for (nm in nms) L[[nm]][] <- na.approx(L[[nm]], na.rm = FALSE)
如果数据框存储在列表中,则更容易做到这一点。然后可以将该函数应用于每个数字列。
library(dplyr)
library(zoo)
l <- c(1,2,5)
list_of_data <- mget(paste0('df', l))
list_of_data <- purrr::map(list_of_data, ~.x %>%
mutate(across(where(is.numeric),
~na.approx(.x, na.rm = FALSE))))
list_of_data
#$df1
# a b c
#1 1 1 1
#2 2 2 2
#3 3 3 3
#4 4 4 4
#5 5 5 5
#6 6 6 6
#7 7 7 7
#8 8 8 8
#9 9 9 NA
#10 NA 10 NA
#$df2
# a b c
#1 1 1 1
#2 2 2 2
#3 3 3 3
#4 4 4 4
#...
#...
如果你想要新的值反映在实际的数据帧中,再次使用list2env
。
list2env(list_of_data, .GlobalEnv)