我是使用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]
如何以最有效的方式对列表中的三个数据框进行子集化? 我认为拉伸并将子集的数量放在向量中是一种很好的方法,但我不知道如何做或者如何在列表中进行子集化。
我希望你能帮助我。在发布之前,我试图在其他帖子中找到一个解决方案,即处理列表中数据框的子集,但这对我的代码不起作用。
答案 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函数(mapply
或pmap
中的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)
我们可以使用purrr包中的.bowerrc
函数。关键是定义一个函数来根据k和列名称获取参数,然后用这些参数组织一个列表,然后使用{
"directory": "src/main/webapp/bower_components",
"allow_root": true
}
。
pmap
数据强>
pmap
答案 3 :(得分:1)
考虑Map
,mapply
的包装器,以返回数据框的列表。并且因为您将一列列为子集,以避免作为向量返回,请使用data.frame
强制转换并使用setNames
重命名。
此处选择了mapply
或Map
,同为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