1

我最近发现了 purrr,我真的很喜欢 map 功能。有谁知道如何解决以下问题:

我有一个数据框,我根据某个变量将其拆分为多个数据框 - 一旦拆分,我想删除结果列表中数据框中唯一的列。在单个数据框中解决这个问题非常容易,但在一个列表中我不太确定 - 你将如何通过使用地图来解决这个问题?

我目前的解决方案如下:

set.seed(123)
dat <- data.frame(target    = round(runif(9, min = 0, max = 1), 0),
                  split_var = c(rep("x", 3), rep("y", 3), rep("z", 3)),
                  var1      = c(rep("a", 3), rep("b", 2), "c", rep("d", 2), "e"),
                  var2      = paste("m", round(rnorm(9, mean = 5), 2), sep = "_"))

mod_dat <- dat %>% split(dat$split_var) 
remover <- function(df){
  non_unique_cols <- sapply(df, function(x) length(unique(x))) > 1
  return(df[, non_unique_cols])
}
map(mod_dat, remover)

还有一个问题,我不想map应用于变量。任何人都可以使用 purrr 包中的地图来帮助执行此操作。removertarget

解决了

@akrun 提供的最终解决方案 - 完全归功于他。

mod_dat <- dat %>% 
  split(.$split_var) %>% 
  map( ~ Filter(function(x) n_distinct(x) > 1, .)) %>% 
  Filter(function(x) sum(names(x) %in% "target"), .)
mod_dat

细微的差别是,在这里我们还删除了删除目标变量的数据帧——出于我的目的,保留这些数据帧并不是必需的。以下代码可用于快速确定保留哪些级别,删除哪些级别。

# In
unique(dat$split_var)[(unique(dat$split_var) %in% names(mod_dat))]
# Out
unique(dat$split_var)[!(unique(dat$split_var) %in% names(mod_dat))]
4

1 回答 1

0

我们可以试试

library(dplyr)
library(purrr)
dat %>% 
   split(.$split_var) %>%
   map(~Filter(function(x) n_distinct(x) >1 , .))

基于 OP 的数据集和更新后的问题,我们可以使用setdiff仅选择所需的列Filter,并且使用bind_cols,我们可以加入“目标”

 dat %>% 
     split(.$split_var) %>% 
     map(~bind_cols(.["target"], Filter(function(x) 
        n_distinct(x) >1 , .[setdiff(names(.), "target")])))
#$x
#  target   var2
#1      0 m_4.89
#2      1 m_4.88
#3      0 m_5.18

#$y
#  target var1   var2
#1      1    b m_6.28
#2      1    b m_3.27
#3      0    c m_6.69

#$z
#  target var1   var2
#1      1    d  m_5.5
#2      1    d m_7.53
#3      1    e m_5.55

数据

dat <- data.frame(v1 = c(rep(1, 3), 4:10), split_var = rep(LETTERS[1:3],
            c(3, 3, 4)), stringsAsFactors=FALSE)
于 2017-01-18T06:50:27.390 回答