【问题标题】:for loop to change columns with a specified unique length to factor in multiple dataframesfor循环更改具有指定唯一长度的列以考虑多个数据帧
【发布时间】:2021-11-25 13:56:15
【问题描述】:

我有几个数据框需要修复多个列的类,然后才能继续。因为数据帧都有相同的变量,但类似乎从一个数据帧到另一个数据帧不同,我想我会去一个“for循环”并指定一个列应该编码为因子或数字的唯一长度。

我尝试了以下因素:

dataframes <- list(dataframe1, dataframe2, dataframe2, dataframe3)

for (i in dataframes){

cols.to.factor <-sapply(i, function(col) length(unique(col)) < 6)

i[cols.to.factor] <- apply(i[cols.to.factor] , factor)
}

现在代码运行了,但它并没有改变任何东西。我错过了什么? 提前感谢您的帮助!

【问题讨论】:

  • apply 应该会报错,试试lapply

标签: r dataframe for-loop code-cleanup


【解决方案1】:

指令

for(i in dataframes)

从列表dataframes 中提取i 并且循环更改副本,该副本永远不会重新分配给原始副本。解决问题的方法是

for (i in seq_along(dataframes)){
  x <- dataframes[[i]]
  cols.to.factor <-sapply(x, function(col) length(unique(col)) < 6)
  x[cols.to.factor] <- lapply(x[cols.to.factor] , factor)
  dataframes[[i]] <- x
}

基于lapply 的等效解决方案是

dataframes <- lapply(dataframes, \(x){
  cols.to.factor <- sapply(x, function(col) length(unique(col)) < 6)
  x[cols.to.factor] <- lapply(x[cols.to.factor], factor)
  x
})

【讨论】:

  • 太棒了!非常感谢。我剩下的唯一问题是,如果我真的检查 dataframe1,类没有改变,而对于 dataframes[1],它是正确的。有没有办法编写它来覆盖原始数据帧?附:我意识到我可以通过 dataframe1
  • @freutopia 如果dataframes 是一个命名列表,请尝试作为for 循环assign(names(dataframes)[i], x, envir = .GlobalEnv) 的最后一条指令。
  • jep,成功了!我只需要在循环之前指定列表中数据帧的名称(名称(数据帧)
【解决方案2】:
library(tidyverse)
# example data
list(
  iris,
  iris %>% mutate(Sepal.Length = Sepal.Length %>% as.character())
) %>%
  # unify column classes
  map(~ .x %>% mutate(across(everything(), as.character))) %>%
  # optional joining if wished
  bind_rows() %>%
  mutate(Species = Species %>% as.factor()) %>%
  as_tibble()
#> # A tibble: 300 x 5
#>    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#>    <chr>        <chr>       <chr>        <chr>       <fct>  
#>  1 5.1          3.5         1.4          0.2         setosa 
#>  2 4.9          3           1.4          0.2         setosa 
#>  3 4.7          3.2         1.3          0.2         setosa 
#>  4 4.6          3.1         1.5          0.2         setosa 
#>  5 5            3.6         1.4          0.2         setosa 
#>  6 5.4          3.9         1.7          0.4         setosa 
#>  7 4.6          3.4         1.4          0.3         setosa 
#>  8 5            3.4         1.5          0.2         setosa 
#>  9 4.4          2.9         1.4          0.2         setosa 
#> 10 4.9          3.1         1.5          0.1         setosa 
#> # … with 290 more rows

reprex package (v2.0.1) 于 2021-10-05 创建

【讨论】:

  • 嘿,谢谢。这不是我想要的,因为我想避免命名实际的列。但是下面的答案非常有帮助。
猜你喜欢
  • 1970-01-01
  • 2020-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-01
  • 2023-03-03
  • 2022-11-28
  • 1970-01-01
相关资源
最近更新 更多