【问题标题】:Getting information from rows above and below从上面和下面的行中获取信息
【发布时间】:2014-10-22 07:53:37
【问题描述】:

我是 R 新手,不知道如何从以下数据中获得正确的输出:

我的数据:

row1    101 woody   5
row2    101 woody   0
row3    111 kiln    23
row4    200 weez    2
row5    315 rowt    0

例如,在第 3 行,第 3 列的元素大于 0,其第 1 列的值介于 101 (row1 ) 和 111 (row3) 之间。所以条件是,对于任何一行,如果第 3 列的值大于 0,并且第 1 列的值介于上列和下列之间。

需要的输出:

        col1 col2   col3
row1    101 woody   After_none
row2    101 woody   0
row3    111 kiln    Between_woody_weez
row4    200 weez    Between_Kiln_rowt
row5    315 rowt    0

如果有人可以帮助我,我会很高兴。谢谢

添加了更多数据来运行 Akru 的代码:

col1    col2    col3
255 mwu 21
77031   netw    0
77031   netw    0
77031   netw    0
82513   cuu 91
88206   cxum    0
88206   cxum    0
88206   cxum    0
188450  xaii    25
188450  xaii    0
188450  xaii    0
188450  xaii    0
188450  xaii    0
199800  aau 0

使用此数据样本运行代码,但输出不太正确:

col1 col2 col3              colN
255  mwu   21        After_none
77031 netw    0              <NA>
77031 netw    0              <NA>
77031 netw    0              <NA>
82513  cuu   91  Between_mwu_netw
88206 cxum    0              <NA>
88206 cxum    0              <NA>
88206 cxum    0              <NA>
188450 xaii   25 Between_netw_cxum
188450 xaii    0              <NA>
188450 xaii    0              <NA>
188450 xaii    0              <NA>
188450 xaii    0              <NA>
199800  aau 0                 <NA>

但预期的输出是:

col1 col2 col3              
255  mwu   21        
77031 netw    0              
77031 netw    0              
77031 netw    0              
82513  Between_mwu_cxum   91
88206 cxum    0              
88206 cxum    0              
88206 cxum    0              
188450 Between_cxum_aau   25 
188450 xaii    0              
188450 xaii    0              
188450 xaii    0              
188450 xaii    0   
199800  aau 0           

或者用额外的列“colN”就可以了

预期输出:

col1 col2 col3              
255  mwu   21        
77031 netw    0              
77031 netw    0              
77031 netw    0              
82513  Between_mwu_cxum   91
88206 cxum    0              
88206 cxum    0              
88206 cxum    0              
188450 Between_cxum_aau   25 
188450 xaii    0              
88450 xaii    0              
188450 xaii    0              
188450 xaii    0   
199800  aau 0   

【问题讨论】:

  • 您的预期输出令人困惑。为什么你有Between_mwu_cxum" for the row 82513? Wouldn't that be Between_netw_cxum`?或者新规则是我们只能从 >0 的行中选择?
  • 很抱歉给您带来了困惑。你是对的阿克伦。它应该是 Between_netw_cxum。
  • 我不明白评论col2 did not include the replacement strings "Between..."。你能澄清一下吗?
  • 你希望它在那里有什么?对于这些行,您显示了没有任何 Between 的预期输出。无论如何,我花了一些时间。
  • 对不起,我只展示了没有替代品的例子。我现在将展示完整的示例。谢谢

标签: r


【解决方案1】:

一种方法是:

  indx <- df$col3 >0
  df$colN <- df$col3
  df$colN[indx] <- sapply(which(indx), function(i) {
      i1 <- 1:(i - 1)
      i2 <- (i + 1):nrow(df)
      indx1 <- with(df, col1[i] > col1[i1])
      indx2 <- with(df, col1[i] < col1[i2])
      if (any(indx1) & any(indx2)) 
       paste("Between", df$col2[i1][max(which(indx1))], df$col2[i2][min(which(indx2))], 
             sep = "_") else df$col3[i]
   })

  df
  #     col1 col2 col3              colN
  #1     255  mwu   21                21
  #2   77031 netw    0                 0
  #3   77031 netw    0                 0
  #4   77031 netw    0                 0
  #5   82513  cuu   91 Between_netw_cxum
  #6   88206 cxum    0                 0
  #7   88206 cxum    0                 0
  #8   88206 cxum    0                 0
  #9  188450 xaii   25  Between_cxum_aau
  #10 188450 xaii    0                 0
  #11 188450 xaii    0                 0
  #12 188450 xaii    0                 0
  #13 188450 xaii    0                 0
  #14 199800  aau    0                 0

更新

如果您想更改col2,只需:

 df$col2[indx] <-sapply(which(indx), function(i) {
     i1 <- 1:(i - 1)
     i2 <- (i + 1):nrow(df)
     indx1 <- with(df, col1[i] > col1[i1])
     indx2 <- with(df, col1[i] < col1[i2])
     if (any(indx1) & any(indx2)) 
     paste("Between", df$col2[i1][max(which(indx1))], df$col2[i2][min(which(indx2))], 
         sep = "_") else df$col2[i] #replaced here
   })

 df
 #    col1              col2 col3
 #1     255               mwu   21
 #2   77031              netw    0
 #3   77031              netw    0
 #4   77031              netw    0
 #5   82513 Between_netw_cxum   91
 #6   88206              cxum    0
 #7   88206              cxum    0
 #8   88206              cxum    0
 #9  188450  Between_cxum_aau   25
 #10 188450              xaii    0
 #11 188450              xaii    0
 #12 188450              xaii    0
 #13 188450              xaii    0
 #14 199800               aau    0

数据

 df <-  structure(list(col1 = c(255L, 77031L, 77031L, 77031L, 82513L, 
 88206L, 88206L, 88206L, 188450L, 188450L, 188450L, 188450L, 188450L, 
 199800L), col2 = c("mwu", "netw", "netw", "netw", "cuu", "cxum", 
 "cxum", "cxum", "xaii", "xaii", "xaii", "xaii", "xaii", "aau"
 ), col3 = c(21L, 0L, 0L, 0L, 91L, 0L, 0L, 0L, 25L, 0L, 0L, 0L, 
 0L, 0L)), .Names = c("col1", "col2", "col3"), class = "data.frame", 
 row.names = c(NA,-14L))

【讨论】:

  • 请问after_none的条件是什么?是重复数(101)的第一个条目吗?
  • @jazzurro 是的,这是第一个条目。我猜它上面没有行,它将被命名为after_none。但是,我对这个问题有点困惑。到目前为止,我还没有收到OP的任何回复。
  • @jazzurro 我猜来自dplyrbetween 可能是另一种选择?
  • 我正在使用 SOfun 包中的getMyRows,它允许我执行类似的过程。我的代码不像你的那样紧凑;我想我不会发布它。您将如何处理between 在这里?
  • @jazzurro 我没有时间考虑这个过程。另外,我没有从 OP 那里得到任何反馈。所以,我会等。
猜你喜欢
  • 2017-10-02
  • 1970-01-01
  • 1970-01-01
  • 2020-07-26
  • 1970-01-01
  • 1970-01-01
  • 2012-07-05
  • 2023-03-21
  • 2014-01-24
相关资源
最近更新 更多