R - 复制组内的值

标签 r copy replicate

我有一个数据框,其中包含某人在过去 3 年(2016 年、2017 年、2018 年)中的总得分,以及他们每年得分的列。

我的数据框如下所示:

myDF <- data.frame(ID =c(1,1,1,2,2,3,4),
 Dates= c("2016", "2017", "2018", "2016", "2017", "2018", "2016"),
 Total_Points = c(5, 5, 5, 4, 4, 2, 3),
 Points2016 = c(3, NA, NA, 2, NA, NA, 3),
 Points2017 = c(NA,1,NA,NA,2,NA,NA),
 Points2018= c(NA,NA,1, NA, NA, 2, NA))

问题是我想为每个组复制列“Points2016”、“Points2017”和“Points2017”的值,以便它们的条目看起来相同。

我不确定解释是否清楚,所以这将是我的预期输出:
myDF_final <- data.frame(ID =c(1,1,1,2,2,3,4),
               Dates= c("2016", "2017", "2018", "2016", "2017", "2018", "2016"),
               Total_Points = c(5, 5, 5, 4, 4, 2, 3),
               Points2016 = c(3, 3, 3, 2, 2, NA, 3),
               Points2017 = c(1,1,1,2,2,NA,NA),
               Points2018= c(1,1,1, NA, NA, 2, NA))

基本上,我希望每个 ID 的“Points201X”列都具有相同的值。

最佳答案

我认为您可以在两个方向都填写 ID 组。使用 dplyrtidyr 我们可以做到:

library(dplyr)
library(tidyr)

myDF %>% 
  group_by(ID) %>% 
  fill(Points2016, Points2017, Points2018) %>% 
  fill(Points2016, Points2017, Points2018, .direction = "up")

返回:

  ID Dates Total_Points Points2016 Points2017 Points2018
1  1  2016            5          3          1          1
2  1  2017            5          3          1          1
3  1  2018            5          3          1          1
4  2  2016            4          2          2         NA
5  2  2017            4          2          2         NA
6  3  2018            2         NA         NA          2
7  4  2016            3          3         NA         NA


另外,如果你有很多年,比如 1970 - 2018,你可以做这样的事情:
myDF %>% 
  gather(points_year, points, -c(ID, Dates, Total_Points)) %>% 
  group_by(ID, points_year) %>% 
  fill(points) %>% 
  fill(points, .direction = "up") %>% 
  spread(points_year, points)

以免年年打字。然而,这涉及收集和传播数据,假设我们需要 fill 的变量遵循一致的命名约定,这可能是不必要的。在这种情况下,有一个一致的命名约定,我们可以使用 tidyselect dplyr 后端来填充所有以单词“Points”开头的变量:
myDF %>% 
  group_by(ID) %>% 
  fill(starts_with("Points"), .direction = "down") %>% 
  fill(starts_with("Points"), .direction = "up")

或者,这似乎适用于 data.tablezoo :
library(data.table)
library(zoo)

dt <- as.data.table(myDF)

dt <- dt[, names(dt)[4:6] := lapply(.SD, function(x) na.locf0(x)), by = ID, .SDcols = 4:6]
dt <- dt[, names(dt)[4:6] := lapply(.SD, function(x) na.locf0(x, fromLast = TRUE)), by = ID, .SDcols = 4:6]

这一类轮似乎也可以一次性完成所有工作:
dt[, names(dt)[4:6] := lapply(.SD, function(x) na.locf(x)), by = ID, .SDcols = 4:6]

   ID Dates Total_Points Points2016 Points2017 Points2018
1:  1  2016            5          3          1          1
2:  1  2017            5          3          1          1
3:  1  2018            5          3          1          1
4:  2  2016            4          2          2         NA
5:  2  2017            4          2          2         NA
6:  3  2018            2         NA         NA          2
7:  4  2016            3          3         NA         NA

关于R - 复制组内的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49256053/

相关文章:

r - 函数对给定字符串长度的可变数量的子字符串进行采样

r - 在 R 中对不同的十六进制颜色进行排序的最佳实践

javascript - 在 iPhone 上的移动 Safari 中选择文本

r - 如何用按平均值着色的较小矩形填充矩形

c++ - 在 C++ 中精确复制对象(构造后的数据集)

javascript - ZeroClipboard 在第一次单击时不起作用

R:当使用rep(..,..)复制1020个a字符变量时,结果只包含1019个重复?

r - 应用系列功能的范围如何?

在R中读取Stata 14文件

r - 当我在数据框中仅使用列名的初始部分时,为什么 R 不会引发错误?