【问题标题】:Shift values in single column of dataframe up向上移动数据框单列中的值
【发布时间】:2014-11-17 16:03:39
【问题描述】:

使用这样的示例数据:

example=data.frame(x=c(1,2,3,4,5,6,7,8), y=c(1,2,3,4,5,6,7,8), z=c(1,2,3,4,5,6,7,8))

看起来像这样:

    x   y   z
1   1   1   1
2   2   2   2
3   3   3   3
4   4   4   4
5   5   5   5
6   6   6   6
7   7   7   7
8   8   8   8

我想将 z 列中的所有值向上移动两行,而数据框的其余部分保持不变。 结果应如下所示:

    x   y   z
1   1   1   3
2   2   2   4
3   3   3   5
4   4   4   6
5   5   5   7
6   6   6   8
7   7   7   NA
8   8   8   NA

我只找到了向下移动列值或移动整个数据框的方法。

有什么想法吗? 谢谢!

【问题讨论】:

标签: r dataframe


【解决方案1】:
## In case you want to shift your rows down by one step for only one column
`z <- example$'z'`

# Deleting the last z value in order to shift values 
# ahead by one period to realign with other rows

z_1 <-head(z,-1)

# We set the initial z value to zero

for (i in 1: (length(z)+1)) {
  if(i != 1){
    z[i] = Z_1[i-1]}
  else{
    z[i] = 0
  }
}
Z
# Append Z to dataframe
example$z <- z

【讨论】:

  • 这基本上是可接受答案的效率较低版本,用for循环替换矢量化操作。 span>
【解决方案2】:

“有用”包中的这个函数可以双向移动列: https://www.rdocumentation.org/packages/useful/versions/1.2.6/topics/shift.column

【讨论】:

  • 最好直接给出解释或至少总结一个解释到你的答案中,而不是在没有进一步帮助的情况下指向一个 URL。
【解决方案3】:
example = tibble(x=c(1,2,3,4,5,6,7,8), 
                   y=c(1,2,3,4,5,6,7,8), 
                   z=c(1,2,3,4,5,6,7,8))

example %>% mutate_at(c("z"), funs(lead), n = 2 )

# A tibble: 8 x 3
      x     y     z
  <dbl> <dbl> <dbl>
1  1.00  1.00  3.00
2  2.00  2.00  4.00
3  3.00  3.00  5.00
4  4.00  4.00  6.00
5  5.00  5.00  7.00
6  6.00  6.00  8.00
7  7.00  7.00 NA   
8  8.00  8.00 NA  

【讨论】:

  • 如何使用这段代码来移动行而不是列?
  • 根据dplyr 文档:Warning message: funs() is deprecated as of dplyr 0.8.0.... 我做了以下轻微更新,它工作正常:example %&gt;% mutate_at(c("z"), tibble::lst("z"=lead), n = 1)
【解决方案4】:

我找不到好的副本,所以这里有另一个使用 length&lt;- 的解决方案

shift2 <- function(x, n) `length<-`(tail(x, -n), length(x)) 
# or just shift2 <- function(x, n) c(tail(x, -n), rep(NA, n))
transform(example, z = shift2(z, 2))   
#   x y  z
# 1 1 1  3
# 2 2 2  4
# 3 3 3  5
# 4 4 4  6
# 5 5 5  7
# 6 6 6  8
# 7 7 7 NA
# 8 8 8 NA

【讨论】:

    【解决方案5】:

    您的问题简化为:

    • 删除向量中的第一个 n 元素
    • 在末尾填充n NA 的值

    你可以用一个简单的函数来做到这一点:

    shift <- function(x, n){
      c(x[-(seq(n))], rep(NA, n))
    }
    
    example$z <- shift(example$z, 2)
    

    结果:

    example
      x y  z
    1 1 1  3
    2 2 2  4
    3 3 3  5
    4 4 4  6
    5 5 5  7
    6 6 6  8
    7 7 7 NA
    8 8 8 NA
    

    【讨论】:

    • c(tail(x, -n), rep(NA, n))。这个问题有重复的味道……
    • 但是什么是 data.table 解决方案!
    • @rawr,一如既往的犀利:)
    • @Andrie 再次感谢您的帮助。我一直在尝试利用它来实现另一个方向的转变(第 1 行和第 2 行中的两个 NA 值,然后是初始系列),但无法弄清楚如何做到这一点。你能帮帮我吗?
    • @Andrie 您能否修改以适用于具有不同班次的多列。说第 1 列您想保持原始状态,但第 2 列您想上移 1 个位置/行,然后第 3 列您想上移 2 个位置...第 4 列上移 3 个位置等...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    相关资源
    最近更新 更多