R:当顺序行值不同时从数据帧中提取值

时间:2015-12-01 17:10:49

标签: r

我有一个包含2列的data.frame df

  • A包含正值。
  • B包含值(零值或正值)。

我希望生成一个包含的新data.frame(或vector)(未知长度) 来自df[i+1, A]的值,仅在df[i, B] == 0 & df[i + 1, B] != 0

我可以通过使用循环顺序逐步执行data.frame来可视化如何执行此操作,但这将永远带有> 200,000行。对于像这样的问题的向量化解决方案是什么,需要对向量或data.frame的连续行进行算术运算?

数据采用以下形式:

      A    B
1     5    5
2    10    3
3    15    0
4    20    6
5    25    5
6    30    0
7    35    0
8    40   11
9    45    3
etc etc  etc

然后,我想从第4行(A)和第8行(A = 20)等中提取A = 40的值。

3 个答案:

答案 0 :(得分:3)

您可以使用

df$A[-1][diff(df$B != 0) > 0]
[1] 20 40

这个想法如下。首先,给定一个向量c(1, 2),提取2的一种方法当然是c(1, 2)[2]。另一种方法是c(1, 2)[c(FALSE, TRUE)],即您可以使用逻辑向量对向量进行子集化。

在您修改了问题之后,我发现我们不再对df的第一行感兴趣,因此这就是我从df$A[-1]开始的原因。然后,一种方式更长,效率更低,但遵循更易读的逻辑,

df$A[-1][df$B[-nrow(df)] == 0 & df$B[-1] != 0]

其中df$B[-1] != 0返回与您的条件df [ i+1, B ] != 0对应的逻辑向量。然后df$B[-nrow(df)] == 0返回与df [ i, B ]==0对应的另一个逻辑向量。然后运算符&执行逐元AND运算,返回最终的逻辑向量并给出结果。

现在diff(df$B != 0) > 0只是编写相同内容的一种棘手的方法。 df$B != 0给出了一个逻辑向量。然后,在执行diff(df$B != 0)时,我们会得到1的差异(对应于条目TRUE)和0'(对应于FALSE)。例如,c(0, 1) != 0提供c(FALSE, TRUE),可以将其视为c(0, 1),然后diff提供1。因此,我们在diff(df$B != 0)中有一个,其中条目0后跟一些非零(在您的情况下为正)数字。要将这些结果用于子集df$A[-1],我们会使用diff(df$B != 0) > 0获取最终的逻辑向量。

答案 1 :(得分:1)

另一种选择来自' dplyr'使用以下代码:

library(dplyr)
df %>% filter(B != 0 & lag(B, 1) == 0)

这使用数据帧并留下B不等于0且先前B等于零的行。这会返回A列和B列。如果您只想查看某些列,请添加%>% select(...),其参数是以逗号分隔的变量。

答案 2 :(得分:0)

我的例子(将两个向量的连续值加在一起):

> i1=c(1:100)
> i2=c(100:1)
> i3=i1[-length(i1)]+i2[-1]
> i3
 [1] 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100
[55] 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100 100

我的例子(将单个向量中的连续值加在一起):

> i1=c(1:100)
> i2=i1[-length(i1)]+i1[-1]
> i2
 [1]   3   5   7   9  11  13  15  17  19  21  23  25  27  29  31  33  35  37  39  41  43  45  47  49  51  53  55  57  59  61  63  65  67  69  71  73  75  77  79  81  83  85  87  89  91  93  95  97  99 101 103 105 107 109
[55] 111 113 115 117 119 121 123 125 127 129 131 133 135 137 139 141 143 145 147 149 151 153 155 157 159 161 163 165 167 169 171 173 175 177 179 181 183 185 187 189 191 193 195 197 199