name score end.s time
1 a 1 NA 1
2 a 2 NA 2
3 a 3 NA 3
4 b 4 4 1
5 b 5 4 2
6 b 6 4 3
7 c 7 NA 1
8 c 8 NA 2
9 d 6 6 1
10 d 7 6 3
我想要的输出:
name score end.s time
1 a 1 3 1
2 a 2 3 2
3 a NA 3 3
4 b 4 4 1
5 b 5 4 2
6 b 6 4 3
7 c 7 8 1
8 c NA 8 2
9 d 6 6 1
10 d 7 6 3
转换有两个功能 - 从'得分'列中取最后一个值来替换'end.s'列中的NA 和从'score'列替换该值与NA。
我认为我可以使用之前帖子中的语法来替换NA,但是一旦我看了一遍并想了一下它就不会那样了。
我在考虑应用函数是可行的方法,但我还是没有成功地完成第一步。
答案 0 :(得分:2)
你想要的是有点复杂,答案也是如此:
library(dplyr)
df %>% group_by(name) %>% mutate(help=last(score)) %>%
mutate(score = ifelse(is.na(end.s), c(score[-n()], NA), score)) %>%
mutate_at(vars(end.s), funs(ifelse(is.na(.), help, .))) %>% select(-help)
## # A tibble: 10 x 4
## # Groups: name [4]
## name score end.s time
## <fctr> <int> <int> <int>
## 1 a 1 3 1
## 2 a 2 3 2
## 3 a NA 3 3
## 4 b 4 4 1
## 5 b 5 4 2
## 6 b 6 4 3
## 7 c 7 8 1
## 8 c NA 8 2
## 9 d 6 6 1
## 10 d 7 6 3
<强> 数据:的强>
df <- structure(list(name = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 3L,
3L, 4L, 4L), .Label = c("a", "b", "c", "d"), class = "factor"),
score = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 6L, 7L), end.s = c(NA,
NA, NA, 4L, 4L, 4L, NA, NA, 6L, 6L), time = c(1L, 2L, 3L,
1L, 2L, 3L, 1L, 2L, 1L, 3L)), .Names = c("name", "score",
"end.s", "time"), row.names = c("1", "2", "3", "4", "5", "6",
"7", "8", "9", "10"), class = "data.frame")
答案 1 :(得分:2)
以下是data.table
library(data.table)
i1 <- setDT(df)[is.na(end.s), .I[.N], name]$V1
df[is.na(end.s), end.s := score[.N], name][i1, score := NA][]
# name score end.s time
# 1: a 1 3 1
# 2: a 2 3 2
# 3: a NA 3 3
# 4: b 4 4 1
# 5: b 5 4 2
# 6: b 6 4 3
# 7: c 7 8 1
# 8: c NA 8 2
# 9: d 6 6 1
#10: d 7 6 3
答案 2 :(得分:1)
我相信以下是你想要的。
test <- do.call(rbind, lapply(split(test, test$name), function(x){
i <- is.na(x$end.s)
x$end.s[i] <- x$score[nrow(x)]
if(any(i)) x$score[nrow(x)] <- NA
x
}))
row.names(test) <- NULL
test