1

我花了大约 20 分钟浏览以前的问题,但找不到我要找的东西。我有一个大数据框,我想根据名称列表对其进行子集化,但是数据框中的名称也可以有列表中未指明的后缀。

换句话说,是否有一种更简单的通用方法(对于无限数量的后缀)来执行以下操作:

data <- data.frame("name"=c("name1","name1_post1","name2","name2_post1",
                            "name2_post2","name3","name4"),
                   "data"=rnorm(7,0,1),
                   stringsAsFactors=FALSE)

names <- c("name2","name3")

subset <- data[ data$name %in% names | data$name %in% paste0(names,"_post1") | data$name %in% paste0(names,"_post2") , ]

回应@Arun的回答。我的数据中的名称实际上包含多个下划线,使问题更加复杂。

data <- data.frame("name"=c("name1_target_time","name1_target_time_post1","name2_target_time","name2_target_time_post1",
                            "name2_target_time_post2","name3_target_time","name4_target_time"),
                   "data"=rnorm(7,0,1),
                   stringsAsFactors=FALSE)

names <- c("name2_target_time","name3_target_time")

subset <- data[ data$name %in% names | data$name %in% paste0(names,"_post1") | data$name %in% paste0(names,"_post2") , ]
4

2 回答 2

3

编辑:使用正则表达式的解决方案(遵循 OP 在评论中的跟进):

data[grepl(paste(names, collapse="|"), data$name), ]
#          name       data
# 3       name2  1.4934931
# 4 name2_post1 -1.6070809
# 5 name2_post2 -0.4157518
# 6       name3  0.4220084

在您的新数据上:

#                      name      data
# 3       name2_target_time 0.6295361
# 4 name2_target_time_post1 0.8951720
# 5 name2_target_time_post2 0.6602126
# 6       name3_target_time 2.2734835

此外,正如@flodel 在评论下显示的那样,这也可以正常工作!

subset(data, sub("_post\\d+$", "", name) %in% names)

旧解决方案:

data[sapply(strsplit(data$name, "_"), "[[", 1) %in% names, ]

#          name       data
# 3       name2  1.4934931
# 4 name2_post1 -1.6070809
# 5 name2_post2 -0.4157518
# 6       name3  0.4220084

想法:首先使用split字符串。这会产生一个列表。例如:将导致(列表的第一个元素)。但会导致和(列表的第二个元素)。通过包装它并使用with ,我们可以只选择这个结果列表的“第一个”元素。然后我们可以使用它来检查它们是否存在(这很简单)。_strsplitname2name2name2_post1name2post1sapply[[1%in%names

于 2013-04-16T19:52:51.257 回答
0

grep 解决方案可能如下所示:

subset <- data[grep("(name2)|(name3)",names(data)),]
于 2013-04-16T20:08:09.617 回答