【问题标题】:selection of rows and their neighboring rows in RR中的行及其相邻行的选择
【发布时间】:2014-12-16 15:15:27
【问题描述】:

我在 R 中遇到了一个简单的问题。我正在处理一个大数据集,我正在尝试选择任何符合特定条件的行,以及数据框中上面的两行和下面的两行。这是我的数据的样子

df <- structure(c("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", 
"11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", 
"22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", 
"33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", 
"44", "45", "46", "47", "48", "49", "50", "a", "b", "a", "a", 
"a", "b", "a", "a", "a", "b", "a", "a", "a", "a", "a", "a", "a", 
"a", "a", "b"), .Dim = c(10L, 7L), .Dimnames = list(NULL, c("1", 
"2", "3", "4", "5", "6", "7")))

我正在寻找第 6 列中带有“b”和第 7 列中带有“a”的实例。可以通过以下命令选择这些实例:

rows <- df[which(df[,6] == "b"& df[,7] =="a"),]

但我不确定如何选择两个更高和两个更低的实例(尤其是符合条件的第一个命中有一个更高的实例)。这应该是基本的,但我想不出一个好的方法来做到这一点。有什么想法吗?

谢谢

【问题讨论】:

  • 这里我得到的索引是行2 and 6。根据您的情况,应该选择其他哪些行?
  • 没错,2和6符合条件。我期待选择每个命中的后续两个较高和两个较低实例(如果它们存在)。所以选择的行应该是 1,2,3,4(因为 2 是命中)和 4,5,6,7,8(因为 6 是命中)。结果将是与第 1 到第 8 行相同的数据框。这有意义吗?
  • 密切相关的问答:stackoverflow.com/q/13155609/1270695

标签: r dataframe selection rows subset


【解决方案1】:

一种方法是:

indx <-  which(df[,6] == "b"& df[,7] =="a")
indx1 <- unique(unlist(lapply(indx, function(x) c(seq(x-2,x), x, seq(x, x+2)))))
df[indx1,]
#     1   2    3    4    5    6   7  
#[1,] "1" "11" "21" "31" "41" "a" "a"
#[2,] "2" "12" "22" "32" "42" "b" "a"
#[3,] "3" "13" "23" "33" "43" "a" "a"
#[4,] "4" "14" "24" "34" "44" "a" "a"
#[5,] "5" "15" "25" "35" "45" "a" "a"
#[6,] "6" "16" "26" "36" "46" "b" "a"
#[7,] "7" "17" "27" "37" "47" "a" "a"
#[8,] "8" "18" "28" "38" "48" "a" "a"

更新

感谢@Ananda Mahto 在代码中找到bug 并提供更短、更紧凑的代码。

indx1 <- Filter(function(x) x > 0, unique(unlist(lapply(indx, "+", -2:2))))
df[indx1,]

【讨论】:

  • 答案再简洁不过了,不是吗?谢谢朋友!
  • @Error404 可以变得更整洁,你永远不知道 :-)
  • @Error404,更整洁:indx1 &lt;- unique(unlist(lapply(indx, "+", -2:2)))。 akrun:您还应该考虑对indx1 进行子集化的另一个步骤,以便只考虑正值。
  • 所以,我猜indx1 &lt;- Filter(function(x) x &gt; 0, unique(unlist(lapply(indx, "+", -2:2))))...
【解决方案2】:

我编写了一个名为getMyRows 的函数,它是my GitHub-only "SOfun" package 的一部分。从本质上讲,它是@akrun 答案的概括,它的行为有点不同——它导致list(因为我设想的预期行为是将相关行保持在一起)。

根据您的数据,使用情况和相关结果将是:

library(SOfun)
getMyRows(df, which(df[, 6] == "b" & df[, 7] == "a"), range = -2:2)
# [[1]]
#      1   2    3    4    5    6   7  
# [1,] "1" "11" "21" "31" "41" "a" "a"
# [2,] "2" "12" "22" "32" "42" "b" "a"
# [3,] "3" "13" "23" "33" "43" "a" "a"
# [4,] "4" "14" "24" "34" "44" "a" "a"
# 
# [[2]]
#      1   2    3    4    5    6   7  
# [1,] "4" "14" "24" "34" "44" "a" "a"
# [2,] "5" "15" "25" "35" "45" "a" "a"
# [3,] "6" "16" "26" "36" "46" "b" "a"
# [4,] "7" "17" "27" "37" "47" "a" "a"
# [5,] "8" "18" "28" "38" "48" "a" "a"

注意事项:range 参数应该写成 : 来表示你想做的事情。


安装包:

library(devtools)
install_github("SOfun", "mrdwab")

(或者你最喜欢的从 GitHub 安装包的方法)。

【讨论】:

  • @akrun,谢谢。大约 2 年前,我写了这个函数 as an answer 的早期版本...... 弗洛德尔在那个问题上的回答也可以适应这个问题。
猜你喜欢
  • 2014-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-09
  • 2014-08-04
  • 1970-01-01
  • 2020-03-25
  • 1970-01-01
相关资源
最近更新 更多