问题:使用如下数据框:
df <- data.frame('ID' = c(1, 1, 1, 1, 2, 2, 2, 2),
'UD' = c(0, 5, 10, 15, 0, 0, 10, 15),
'LD' = c(5, 10, 15, 20, 5, 10, 15, 20),
'VAL' = c(1.2, 3.6, 5.7, 8.0, 5.2, 5.6, 8.7, 3.1))
对于每个ID组,LD的值必须与下一行的UD值相匹配。所以df[6, 2]
应为5,而不是0。
我一直试图编写一个可以在这样的数据框中移动并进行这种修正的函数。我想我已接近以下内容,但编辑后的值正在被覆盖,因为rollapply
重新组合其输出。
fix <- function(df) {
df2 <- by(df, as.factor(df$ID), FUN = function(x) {
rollapply(x, width = 2, FUN = function(y) {
y[2, 2] <- ifelse(y[2, 2] != y[1, 3], y[1, 3], y[2, 2])
print(y) # test
return(y)
}, by.column = FALSE)
print('x:') # test
print(x) # test
return(x)
})
out <- do.call('rbind', df2)
return(out)
}
有没有办法解决这个问题,或者是解决问题的更好的替代方法?
编辑 - 预期输出:
df2 <- data.frame('ID' = c(1, 1, 1, 1, 2, 2, 2, 2),
'UD' = c(0, 5, 10, 15, 0, 5, 10, 15),
'LD' = c(5, 10, 15, 20, 5, 10, 15, 20),
'VAL' = c(1.2, 3.6, 5.7, 8.0, 5.2, 5.6, 8.7, 3.1))
答案 0 :(得分:2)
您可以使用dplyr
。按“ID”对数据进行分组,然后将“UD”设置为与“LD”相同,但相移一次(使用mutate
和lag
)。当你得到一个新的'ID'时,将第一个设置为0(NA是默认值)。
library(dplyr)
fixed_df <- df %>%
group_by(ID) %>%
mutate(UD = lag(LD, default = 0))
fixed_df
#Source: local data frame [8 x 4]
#Groups: ID [2]
#
# ID UD LD VAL
# <dbl> <dbl> <dbl> <dbl>
#1 1 0 5 1.2
#2 1 5 10 3.6
#3 1 10 15 5.7
#4 1 15 20 8.0
#5 2 0 5 5.2
#6 2 5 10 5.6
#7 2 10 15 8.7
#8 2 15 20 3.1
答案 1 :(得分:2)
我们可以使用data.table
。将'data.frame'转换为'data.table'(setDT(df)
),按'ID'分组,我们指定(:=
)'{1}}'LD'({{1 }})作为'UD'列
lag