R 使用具有多个功能输入的Lappy,无需嵌套
我有一个数据框,有四列:两列表示参加了一项运动,而另外两列表示运动员是否通过了两次体能测试R 使用具有多个功能输入的Lappy,无需嵌套,r,lapply,R,Lapply,我有一个数据框,有四列:两列表示参加了一项运动,而另外两列表示运动员是否通过了两次体能测试 dat <- data.frame(SOCCER = sample(0:1, 10, replace = T), BASEBALL = sample(0:1, 10, replace = T), TEST_1_PASS = sample(0:1, 10, replace = T), TEST_
dat <- data.frame(SOCCER = sample(0:1, 10, replace = T),
BASEBALL = sample(0:1, 10, replace = T),
TEST_1_PASS = sample(0:1, 10, replace = T),
TEST_2_PASS = sample(0:1, 10, replace = T))
我想获得一份包含每项运动和考试的列联表的列表。我知道我可以使用下面的代码来实现这一点,它使用嵌套的Lappy语句,但这让我觉得效率很低。有人能提出一个不使用嵌套的更优雅的解决方案吗
results <- lapply(c("SOCCER", "BASEBALL"), function(x) {
lapply(c("TEST_1_PASS", "TEST_2_PASS"), function(y){
table(sport = dat[[x]], pass = dat[[y]])
})
})
一如既往地谢谢你 double-lappy获取每个列向量中的所有列的成对组合,就像在注释中写的那样
我不认为你的筑巢是低效的。。。你需要叫4号桌 时代。它是否在一个循环/重叠中并不重要 4个项目或2个嵌套循环/套圈,每个项目2个 但这里有另一种方法,其中一个循环伪装成expand.grid double-lappy获取每个列向量中的所有列的成对组合,就像在注释中写的那样
我不认为你的筑巢是低效的。。。你需要叫4号桌 时代。它是否在一个循环/重叠中并不重要 4个项目或2个嵌套循环/套圈,每个项目2个 但这里有另一种方法,其中一个循环伪装成expand.grid
考虑将数据重新格式化为长格式,即合并sport和exam的两个数据段,然后由apply家族中很少使用的成员作为面向对象的包装器运行,以tapply为这两个数据段之间的所有子集组合返回一个命名的结果标题报告:
# RESHAPE EACH DATA SECTION (SPORT AND EXAM) INTO LONG FORMAT
df_list <- lapply(list(c("SOCCER", "BASEBALL"), c("TEST_1_PASS", "TEST_2_PASS")), function(cols)
reshape(cbind(PLAYER = row.names(dat), dat[cols]),
varying = cols, v.names = "VALUE",
times = cols, timevar = "INDICATOR",
idvar = "PLAYER", ids = NULL,
new.row.names = 1:1E4, direction = "long")
)
# CROSS JOIN (ALL COMBINATION PAIRINGS)
final_df <- Reduce(function(x,y) merge(x, y, by="PLAYER", suffixes=c("_SPORT", "_EXAM")), df_list)
final_df
# RUN TABLES FOR EACH SUBSET COMBINATION
tables_list <- with(final_df, by(final_df, list(INDICATOR_SPORT, INDICATOR_EXAM), function(sub)
table(sport = sub$VALUE_SPORT, pass = sub$VALUE_EXAM)
)
)
考虑将数据重新格式化为长格式,即合并sport和exam的两个数据段,然后由apply家族中很少使用的成员作为面向对象的包装器运行,以tapply为这两个数据段之间的所有子集组合返回一个命名的结果标题报告:
# RESHAPE EACH DATA SECTION (SPORT AND EXAM) INTO LONG FORMAT
df_list <- lapply(list(c("SOCCER", "BASEBALL"), c("TEST_1_PASS", "TEST_2_PASS")), function(cols)
reshape(cbind(PLAYER = row.names(dat), dat[cols]),
varying = cols, v.names = "VALUE",
times = cols, timevar = "INDICATOR",
idvar = "PLAYER", ids = NULL,
new.row.names = 1:1E4, direction = "long")
)
# CROSS JOIN (ALL COMBINATION PAIRINGS)
final_df <- Reduce(function(x,y) merge(x, y, by="PLAYER", suffixes=c("_SPORT", "_EXAM")), df_list)
final_df
# RUN TABLES FOR EACH SUBSET COMBINATION
tables_list <- with(final_df, by(final_df, list(INDICATOR_SPORT, INDICATOR_EXAM), function(sub)
table(sport = sub$VALUE_SPORT, pass = sub$VALUE_EXAM)
)
)
你一定要连续性表还是每项运动的平均成功率和成功次数?特别是列联表。需要他们来做一大堆费舍尔测试。那么,球员指标在哪里?请按建议输出实际数据:。我不认为您的嵌套效率低下。。。你需要给桌子打4次电话。如果在一个循环/lapply中包含4个项目,或者在两个嵌套循环/lapply中分别包含2个项目,那么这并不重要。如果切换到purr,您可以稍微清理一下语法,例如,将~用于匿名函数,并且使用purr::map而不是lappy,可以在结果列表中获得更好的名称,但基本上是一样的。你一定要连续表还是每项运动成功的平均数和数量?特别是列联表。需要他们来做一大堆费舍尔测试。那么,球员指标在哪里?请按建议输出实际数据:。我不认为您的嵌套效率低下。。。你需要给桌子打4次电话。如果在一个循环/lapply中包含4个项目,或者在两个嵌套循环/lapply中分别包含2个项目,那么这并不重要。如果切换到purr,您可以稍微清理一下语法,例如,将~用于匿名函数,并且使用purr::map而不是lappy,可以在结果列表中获得更好的名称,但基本上是一样的。我想你也可以做do.callMap,cf=function。。。表DAT[c..],cols@akrun美好的发帖作为回答?与我的答案不同,这些表都有名称。这只是对你的答案稍加修改。我想你也可以这样做。callMap,cf=function。。。表DAT[c..],cols@akrun美好的发帖作为回答?与我的答案不同,这些表格都有名字。这只是对你的答案的一点修改。
tables_list
# : BASEBALL
# : TEST_1_PASS
# pass
# sport 0 1
# 0 3 4
# 1 2 1
# ------------------------------------------------------------
# : SOCCER
# : TEST_1_PASS
# pass
# sport 0 1
# 0 2 0
# 1 3 5
# ------------------------------------------------------------
# : BASEBALL
# : TEST_2_PASS
# pass
# sport 0 1
# 0 3 4
# 1 1 2
# ------------------------------------------------------------
# : SOCCER
# : TEST_2_PASS
# pass
# sport 0 1
# 0 2 0
# 1 2 6