R:对列表中的所有数据帧进行子集

时间:2018-04-07 20:18:42

标签: r list dataframe

我是使用R和stackoverflow的新手。我正在尝试处理数据框列表并遇到以下问题(希望,这是一个很好的再现示例)。假设我有一个包含4列的3个数据帧列表(我的实际代码包含10个数据帧,包含20列):

df1 <- data.frame(k=20:0, h_1=rnorm(21), h_2=rnorm(21), h_3= rnorm(21))
df2 <- data.frame(k=20:0, h_1=rnorm(21), h_2=rnorm(21), h_3= rnorm(21))
df3 <- data.frame(k=20:0, h_1=rnorm(21), h_2=rnorm(21), h_3= rnorm(21))
df_list <- list(df1=df1,df2=df2,df3=df3)

对于每个数据框,我有一个不同的子集条件:

例如:

#If I would subset them in a singular way outside of the list

df1_s <- df1[which(df1$k <=12 & df1$k >0), df1$h_1] #Taking only rows of k=12 to k=1 
and only the column h_1
df2_s <- df2[which(df2$k <=4 & df2$k >0), df2$h_3]
df3_s <- df3[which(df3$k <=12 & df2$k >0), df2$h_2]

如何以最有效的方式对列表中的三个数据框进行子集化? 我认为拉伸并将子集的数量放在向量中是一种很好的方法,但我不知道如何做或者如何在列表中进行子集化。

我希望你能帮助我。在发布之前,我试图在其他帖子中找到一个解决方案,即处理列表中数据框的子集,但这对我的代码不起作用。

4 个答案:

答案 0 :(得分:2)

这是mapply方法(与其他答案相同的想法):

# function: w/ arguments dataframe and a vector = [column name, upper, lower]
rook <- function(df, par) {
  out <- df[par[1]][, 1]
  out[out <= par[2] & out > par[3]]
}

# list of parameters
par_list <- list(
  c('h_1', 12, 0),
  c('h_3', 4 , 0),
  c('h_2', 12, 0)
)

# call mapply
mapply(rook, df_list, par_list)

答案 1 :(得分:2)

这是一个使用基础R的解决方案。如@www所提到的,我们的想法是使用apply-type函数(mapplypmap中的purrr)将多个参数应用于按顺序运作。该解决方案还利用eval-parse构造来进行灵活的子集化。参见例如这里的讨论http://r.789695.n4.nabble.com/using-a-condition-given-as-string-in-subset-function-how-td1676426.html

subset_fun <- function(data, criteria, columns) {
  subset(data, eval(parse(text = criteria)), columns)
}

criterion <- list("k <= 12 & k > 0", "k <= 4 & k > 0", "k <= 12 & k > 0")
cols <- list("h_1", "h_3", "h_2")

out <- mapply(subset_fun, df_list, criterion, cols)
str(out)
# List of 3
#  $ df1.h_1: num [1:12] -0.0589 1.0677 0.2122 1.4109 -0.6367 ...
#  $ df2.h_3: num [1:4] -0.826 -1.506 -1.551 0.862
#  $ df3.h_2: num [1:12] 0.8948 0.0305 0.9131 -0.0219 0.2252 ...

答案 2 :(得分:1)

我们可以使用包中的.bowerrc函数。关键是定义一个函数来根据k和列名称获取参数,然后用这些参数组织一个列表,然后使用{ "directory": "src/main/webapp/bower_components", "allow_root": true }

pmap

数据

pmap

答案 3 :(得分:1)

考虑Mapmapply的包装器,以返回数据框的列表。并且因为您将一列列为子集,以避免作为向量返回,请使用data.frame强制转换并使用setNames重命名。

此处选择了mapplyMap,同为lapply的兄弟,因为您希望在等长对象列表中按元素进行迭代。 Mapply使用无限数量的参数,这里是4,要求长度相等或长度的倍数:

low_limits <- c(0, 0, 0)
high_limits <- c(12, 4, 12)
h_cols <- c("h_1", "h_2", "h_3")

subset_fct <- function(df, lo, hi, col)  
               setNames(data.frame(df[which(df$k > lo & df$k <= hi), col]), col)

new_df_list <- Map(subset_fct, df_list, low_limits, high_limits, h_cols)

# EQUIVALENT CALL
new_df_list <- mapply(subset_fct, df_list, low_limits, 
                      high_limits, h_cols, SIMPLIFY = FALSE)

输出 (在顶部使用set.seed(456)重现随机数)

new_df_list

# $df1
#           h_1
# 1   1.0073523
# 2   0.5732347
# 3  -0.9158105
# 4   1.3110974
# 5   0.9887263
# 6   1.6539287
# 7  -1.4408052
# 8   1.9473564
# 9   1.7369362
# 10  0.3874833
# 11  2.2800340
# 12  1.5378833

# $df2
#           h_2
# 1  0.11815133
# 2  0.86990262
# 3 -0.09193621
# 4  0.06889879

# $df3
#           h_3
# 1  -1.4122604
# 2  -0.9997605
# 3  -2.3107388
# 4   0.9386188
# 5  -1.3881885
# 6  -0.6116866
# 7   0.3184948
# 8  -0.2354058
# 9   1.0750520
# 10 -0.1007956
# 11  1.0701526
# 12  1.0358389