假设我有一个这样的数据集,在这个例子中有三列。有文本行,在这些行之间是带数字的行(我想要的数据)。如果我想要两个特定文本行之间的数据,您将如何识别特定行,并在行之间对数据进行子集化?例如,假设我想要行与c的行和行与d的数据。
col1 col2 col3
a a a
a a a
1 1 1
2 2 2
3 3 3
b b b
3 3 3
c c c
4 4 4
5 5 5
d d d
到
4 4 4
5 5 5
答案 0 :(得分:6)
如果您需要根据所有列中的相同元素对数据进行子集化,则一个选项是使用interaction
粘贴行,使用grep
查找与之匹配的行的索引string,获取索引行(:
)和子集之间的行序列。
indx1 <- as.character(interaction(df, sep=''))
indx2 <- grep('ccc|ddd', indx1)
df[(indx2[1]+1):(indx2[2]-1),]
# col1 col2 col3
#9 4 4 4
#10 5 5 5
在提供的示例中,只有发生这种情况的实例。假设您有多个实例,您可以在ccc
,ddd
字符串与Map
索引,子集和rbind
列表元素之间获得相应的序列。
indx1 <- as.character(interaction(df1, sep=''))
do.call(rbind,Map(function(x,y) df1[(x+1):(y-1),],
grep('ccc', indx1), grep('ddd', indx1)))
我意识到在数据集中可能存在“ccc”行可能没有对应的“ddd”行或者存在多个“ddd”行等的情况。在这种情况下创建索引(“indx2”)将数据集转换为逻辑矩阵(df2!='c'
)。对每行(rowSums
)求和。结果将是数字向量。这里'0'表示该行具有全部'c'。取消索引(!
)以将“0”值转换为“TRUE”和cumsum
。将数据集(split
)拆分为第一行ccc
行之前的行之后的列表。检查每个列表元素中是否都有“d”(!rowSums(x!='d')
)行。如果有任何行(if(any(..
),则根据索引(x
)对数据集(2:(which(i1)[1]-1)
)进行子集,最后对列表元素进行rbind
。
indx2 <- cumsum(!rowSums(df2!='c'))
lst <- split(df2[indx2!=0,], indx2[!!indx2])
res <- do.call(rbind,lapply(lst, function(x) {
i1 <- !rowSums(x!='d')
if(any(i1)) x[2:(which(i1)[1]-1),]}))
df <- structure(list(col1 = c("a", "a", "1", "2", "3", "b", "3", "c",
"4", "5", "d"), col2 = c("a", "a", "1", "2", "3", "b", "3", "c",
"4", "5", "d"), col3 = c("a", "a", "1", "2", "3", "b", "3", "c",
"4", "5", "d")), .Names = c("col1", "col2", "col3"), class =
"data.frame", row.names = c(NA, -11L))
df1 <- structure(list(col1 = c("a", "a", "1", "2", "3", "b", "3",
"c", "4", "5", "d", "3", "b", "3", "c", "4", "5", "d"), col2 =
c("a", "a", "1", "2", "3", "b", "3", "c", "4", "5", "d", "3", "b",
"3", "c", "4", "5", "d"), col3 = c("a", "a", "1", "2", "3", "b",
"3", "c", "4", "5", "d", "3", "b", "3", "c", "4", "5", "d")), .Names
= c("col1", "col2", "col3"), class = "data.frame", row.names = c(NA,
-18L))
df2 <- structure(list(col1 = c("a", "a", "1", "2", "3", "b", "3", "c",
"4", "5", "d", "3", "b", "3", "c", "4", "5", "d", "4", "5", "d",
"c", "4", "5"), col2 = c("a", "a", "1", "2", "3", "b", "3", "c",
"4", "5", "d", "3", "b", "3", "c", "4", "5", "d", "4", "5", "d",
"c", "4", "5"), col3 = c("a", "a", "1", "2", "3", "b", "3", "c",
"4", "5", "d", "3", "b", "3", "c", "4", "5", "d", "4", "5", "d",
"c", "4", "5")), .Names = c("col1", "col2", "col3"), class =
"data.frame", row.names = c(NA, -24L))