首页 > 解决方案 > 如何使用多个变量对多个数据框进行子集化

问题描述

我想根据一系列 31 个变量对五个数据框进行子集化。数据帧存储在一个列表中:

long_data_sets <- list(scale_g1, scale_g2, scale_g3, scale_g4, scale_g5)

五个数据帧中的每一个都包含相同的列集,其中包括 31 个因子,称为“speeder_225”到“speeder_375”:

> str(scale_g1[53:83])
'data.frame':   5522 obs. of  31 variables:
$ speeder_225: Factor w/ 2 levels "Non-Speeder",..: 1 1 1 1 1 1 1 1 1 1 ...
$ speeder_230: Factor w/ 2 levels "Non-Speeder",..: 1 1 1 1 1 1 1 1 1 1 ...
$ speeder_235: Factor w/ 2 levels "Non-Speeder",..: 1 1 1 1 1 1 1 1 1 1 ...
$ speeder_240: Factor w/ 2 levels "Non-Speeder",..: 1 1 1 1 1 1 1 1 1 1 ...
$ speeder_245: Factor w/ 2 levels "Non-Speeder",..: 1 1 1 1 1 1 1 1 1 1 ... 
...

我想一次根据 31 个因子变量之一对数据帧进行子集化,以便最终得到 5*31 个新数据帧。

我创建了子集函数,它只保留了我需要的两列(“方向”和“响应”):

create_speeder_data <- function(x, y){
  df <- subset(x, x[,y] == "Speeder",
              select = c("direction", "response"))
}

这允许我一次创建一个新的数据框:

create_speeder_data(scale_g1, "speeder_225")

我尝试使用 map2() 和 5 个数据框的列表以及 31 个因子名称的列表来应用该函数,但这显然不起作用。

> speeder_var <- names(scale_g1[53:83])
> map2(long_data_sets, speeder_var, create_speeder_data)
Error: `.x` (5) and `.y` (31) are different lengths

我能得到的最接近的方法是从我的函数中取出 y 参数,并将函数应用于 31 个因子之一的五个数据框列表。

#Create subsetting function for "speeder_225"
create_speeder_225_data <- function(x){
  df <- subset(x, x$speeder_225 == "Speeder",
               select = c("direction", "response"))
}

#Map function to list of data frames
z_speeder_225 <- map(long_data_sets, create_speeder_225_data)

#Change names of new data frames in list
names(long_data_sets) <- c("g1", "g2", "g3", "g4", "g5")
names(z_speeder_225) <- paste0(names_long_data_sets, "speeder_225")

#Get data frames from list
list2env(z_speeder_225, envir=.GlobalEnv)

我需要再重复 30 次才能得到我的 5*31 数据帧。必须有一种更简单的方法来做到这一点。

任何帮助深表感谢!

标签: r

解决方案


我同意@Mako212 - 你可能需要重新考虑你想要做什么。但是,这里有一些应该起作用的东西。

下面的代码将对列表中的每个数据集进行子集化。在测试数据中有 5 个分类变量,每个变量有两个水平。由于 otuput 仅基于 1 个级别 ( speeding),因此输出将是 5 x 5 = 25 个数据集。这被组织为列表列表 (5 x 5):

library(data.table)

# Creating some dummy data
k  <- 100
directions <- as.vector(sapply(c('North', 'West', 'South', 'East'), function (z) return(rep(z, k))))
speeding <- as.vector(sapply(c('speeding', 'not-speeding'), function (z) return(rep(z, k))))

# Test data - number_of_observations <= 4*k
createDataTable <- function(number_of_observations = 50){
  dt <- data.table(direction = sample(x = directions, size = number_of_observations, replace = T), 
                   speeder1 = sample(x = speeding, size = number_of_observations, replace = T), 
                   speeder2 = sample(x = speeding, size = number_of_observations, replace = T),
                   speeder3 = sample(x = speeding, size = number_of_observations, replace = T),
                   speeder4 = sample(x = speeding, size = number_of_observations, replace = T),
                   speeder5 = sample(x = speeding, size = number_of_observations, replace = T))
}

data_list <- lapply(X = floor(runif(n = 5, min = 50, max = 4*k)), 
                    FUN = function(z){createDataTable(z)})

# Subset dummy data based on one column at a time and return 
# the number of observations, direction, speeder2 and speeder3 from the subset 
cols <- sapply(1:5, function(z) paste('speeder',z,sep = ""))

ret <- lapply(cols, function(z){
  lapply(data_list, function(x){
    return(x[get(z) == 'speeding', .(nrows = .N, direction, speeder2, speeder3)])
  })
})

的结构ret与我们预期的一致。每个项目都是 5 个data.table对象的列表,每个对象有 4 列。

> summary(ret)
     Length Class  Mode
[1,] 5      -none- list
[2,] 5      -none- list
[3,] 5      -none- list
[4,] 5      -none- list
[5,] 5      -none- list
> summary(ret[[1]])
     Length Class      Mode
[1,] 4      data.table list
[2,] 4      data.table list
[3,] 4      data.table list
[4,] 4      data.table list
[5,] 4      data.table list

快速测试以查看代码是否运行良好并且没有错误地设置子集,这是一个简化的调用,仅包含子集标准的观察数/行数:

> unlist(lapply(cols, function(z){
+     lapply(data_list, function(x){
+         return(x[get(z) == 'speeding', .(nrows = .N)])
+     })
+ }))
nrows nrows nrows nrows nrows nrows nrows nrows nrows nrows nrows nrows nrows nrows nrows nrows nrows 
  113    82    24   112   185    97    63    22   110   193   103    78    35   115   197   110    74 
nrows nrows nrows nrows nrows nrows nrows nrows 
   26   103   194   107    84    25    97   191 

推荐阅读