【问题标题】:Subset a dataframe excluding rows in another dataframe子集一个数据帧,不包括另一个数据帧中的行
【发布时间】:2018-06-22 16:08:18
【问题描述】:

我正在尝试使用 R 中的循环构建多个数据集以进行交叉验证。我有以下代码:

for (i in 1:10) {
  as.data.frame(assign(paste("c",i,sep="_"),dd[((100*i)-99):(100*i),]))
  as.data.frame(assign(paste("t",i,sep="_"),subset(dd,-c_[[i]])))     
}

因此,循环中的第一行有效并正确创建了我的控制集,但我似乎无法弄清楚如何将训练集创建为我的初始数据的子集,不包括控制集中的行。

基于使用新创建的 c_i 数据帧的方法和基于重复第一行条件的方法似乎都不起作用。

对于这个看似简单的问题,我深表歉意,我对 R 和一般编程还很陌生。

感谢您的帮助! :)

【问题讨论】:

  • 您能分享一些可重复使用的数据吗?我不知道'dd'是什么
  • 数据本身对于我想要做的事情并不重要,但我的 dd 集只是由 Uplift 包中的 sim_pte 函数生成的模拟 Uplift 数据。所以它有两个二元变量 y 和treat,以及 5 个随机协变量 X1 到 X5 和一个代表真实升力的变量 ts。在这种情况下,我有 1000 次观察并试图将 CV 提高 10 倍,因此循环中变量 i 的 *100 乘数。

标签: r


【解决方案1】:

重新考虑构建单独的数据框来淹没您的全球环境,并使用assign 这样做。相反,构建 两个 数据帧列表来保存结构相似的 10 个数据帧。对于控制/训练拆分,在组变量上使用split,反之则使用by。

# RESET ROW NAMES IF NOT NEEDED
row.names(dd) <- NULL      

# CREATE A GROUP COLUMN (MULTIPLES OF 100: df_0, df_100 ... df_900)
dd$grp <- paste0("df_", as.integer((as.integer(row.names(dd))-1) / 100) * 100)

# NAMED LIST OF df_0, df_100 ... df_900 (EACH NROWS = 100)
control_dflist <- split(dd, dd$grp)  # OR by(dd, dd$grp, identity)

# NAMED LIST OF df_0, df_100 ... df_900 (EACH NROWS = 900)
training_dflist <- by(dd, dd$grp, function(sub) subset(dd, grp!= max(sub$grp)))

请注意:如果数据框位于命名列表而不是单独的对象中,则不会丢失数据框的功能。

head(control_dflist$df_0)        # 1ST CONTROL DF
summary(control_dflist$df_100)   # 2ND CONTROL DF
tail(control_dflist$df_200)      # 3RD CONTROL DF

关于随机数据的演示:

set.seed(6222018)
dd <- data.frame(
  ID = replicate(1000, sample(seq(15), 1, replace=TRUE)),
  TOOL = replicate(1000, sample(c("julia","r","pandas","spss","stata","sas"), 1, replace=TRUE)),
  NUM = rnorm(1000)*100
)

control_dflist <- by(dd, dd$grp, identity)
training_dflist <- by(dd, dd$grp, function(sub) subset(dd, grp!= max(sub$grp)))

输出 (显示编号和命名的引用;保留行名以供说明)

head(control_dflist[[1]])
#   ID  TOOL        NUM  grp
# 1  4   sas   80.44873 df_0
# 2  5     r -204.50714 df_0
# 3  2  spss -111.54602 df_0
# 4  8 julia -145.48614 df_0
# 5  2   sas  103.82625 df_0
# 6  6  spss  -58.82708 df_0

head(training_dflist[[1]])
#     ID  TOOL       NUM    grp
# 101 10   sas -19.82463 df_100
# 102  4  spss  78.58277 df_100
# 103  2 stata  26.53858 df_100
# 104 13   sas 190.65434 df_100
# 105  1     r  36.96777 df_100
# 106 12     r 133.77021 df_100

tail(control_dflist$df_0)
#     ID  TOOL         NUM  grp
# 95   3 stata   13.446515 df_0
# 96   3  spss  171.488068 df_0
# 97  11   sas   48.573506 df_0
# 98  10     r -132.522866 df_0
# 99  12 stata -155.558407 df_0
# 100  2 stata    7.590873 df_0

tail(training_dflist$df_0)
#      ID  TOOL         NUM    grp
# 995   3  spss   92.613934 df_900
# 996  11  spss   13.389638 df_900
# 997  15 julia -147.108295 df_900
# 998   3 stata   91.032385 df_900
# 999   4   sas  -21.505796 df_900
# 1000 15   sas   -9.771332 df_900

【讨论】:

  • 哦,这是一个聪明的解决方案。从来没有想过要创建一个组变量,但这确实非常适合我的目的。感谢您的详细解答和建议!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-07
  • 2013-06-14
  • 1970-01-01
  • 1970-01-01
  • 2016-02-20
  • 1970-01-01
相关资源
最近更新 更多