我花了大约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") , ]
答案 0 :(得分: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
使用_
的{{1}}字符串strsplit
。这导致列表。例如:name2
将只生成name2
(列表的第一个元素)。但name2_post1
会产生name2
和post1
(列表的第二个元素)。通过使用sapply
并使用[[
1
包裹它,我们可以只选择此结果列表中的“第一个”元素。然后,我们可以将其与%in%
一起使用来检查它们是否存在于names
中(这很简单)。
答案 1 :(得分:0)
grep解决方案可能类似于以下内容:
subset <- data[grep("(name2)|(name3)",names(data)),]