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

R 按条件更改数据帧中的值:较长的对象长度不是较短对象长度的倍数,r,rstudio,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 = 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
我能行

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

或者我会感谢任何更方便、更简短的方法。

R
中的索引从1开始。当我们取
dt$id-1
时,对于'id=1,它变为0,并使用该值进行索引

dt$A[0]
#character(0)
导致
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

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

ifelse
要求所有参数的长度相同。从您的代码来看,它看起来不像
dt$A[dt$id-1]
dt$id
为1时的值是多少<代码>R索引从1开始。它制造了问题。我认为您需要的是
ifelse(dt$A==lag(dt$A),
它也可以
ifelse(dt$A==lag(dt$A),as.character(lag(dt$B)),as.character(dt$A))
谢谢
dt$A[0]
#character(0)
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
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)