根据条件更改数据帧中的值:较长的对象长度不是较短的对象长度的倍数

时间:2019-07-04 20:46:48

标签: r rstudio

对不起,在 较长的物体长度不是较短的物体长度的倍数 的问题中,我找不到正确的答案 我有一个这样的数据框

dt = data.frame(id = c(1,2,3,4,5), A=c('a', 'a', 'c', 'b','b'), B= c('d', 'd','h', 'd', 'd'))

我想得到

  id A B final
1  1 a d  <NA>
2  2 a d     d
3  3 c h     c
4  4 b d     b
5  5 b d     d

我愿意

dt$A = ifelse(dt$A[dt$id] == dt$A[dt$id-1], as.character(dt$B[dt$id-1]), as.character(dt$A))
Warning message:
In dt$A[dt$id] == dt$A[dt$id - 1] :
  longer object length is not a multiple of shorter object length

我能做

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

dt$sht <- shift(as.character(dt$A), 1)
dt$new = ifelse(dt$sht == dt$A, as.character(dt$B), as.character(dt$A[dt$id+1]))
temp = dt$new 
temp=append(NA, temp)
temp = temp[-6]
dt$final = temp
dt[, c(1,2,3,6)]

  id A B final
1  1 a d  <NA>
2  2 a d     d
3  3 c h     c
4  4 b d     b
5  5 b d     d

但这是很长的路要走,我认为您可以更正公式中的错误

dt$A = ifelse(dt$A[dt$id] == dt$A[dt$id-1], as.character(dt$B[dt$id-1]), as.character(dt$A))

否则,我将不胜感激任何更便捷,更简短的方法。

1 个答案:

答案 0 :(得分:2)

R中的索引从1开始。当我们使用dt$id -1时,对于'id = 1,它变为0,并且索引返回

dt$A[0]
#character(0)

导致length的不同自变量在ifelse中有所不同。

  

ifelse(测试,是,否)

     

如果是或否太短,则将其元素回收。当且仅当测试的任何一个要素为真,并且类似地为否,才会评估是。


相反,我们可以利用lag

library(dplyr)
dt %>% 
    mutate(final = case_when(A == lag(A, default = A[1]) ~ lag(B), TRUE ~ A))
#  id A B final
#1  1 a d  <NA>
#2  2 a d     d
#3  3 c h     c
#4  4 b d     b
#5  5 b d     d

在这里,也可以用ifelse替换它,并且根据?case_when

  

此功能允许您向量化多个if_else()语句。

数据

dt = data.frame(id = c(1,2,3,4,5), A=c('a', 'a', 'c', 'b','b'), 
   B= c('d', 'd','h', 'd', 'd'), stringsAsFactors = FALSE)

注意:默认情况下,stringsAsFactors = TRUE。通过将其更改为FALSE,可以避免在创建数据集后进行多次as.character转换