我对R相对较新,并且编程一般,并且有一个包含两列的数据框,例如:
X <- c(2010,2011,2012,2013,2014)
Y <- c(1,2,3,4,5)
DATA <- data.frame(X,Y)
现在我想创建一些等于行数减一的新列。第一个新创建的列应该从第二行开始,每个附加列应该从前一列开始一个(直到创建一个值的最后一列)。 值应取自上面一行的Y列。
所需的输出如下:
X <- c(2010,2011,2012,2013,2014)
Y <- c(1,2,3,4,5)
NEW_COLUMN_1 <- c(NA,1,2,3,4)
NEW_COLUMN_2 <- c(NA,NA,2,3,4)
NEW_COLUMN_3 <- c(NA,NA,NA,3,4)
NEW_COLUMN_4 <- c(NA,NA,NA,NA,4)
DATA <- data.frame(X,Y,NEW_COLUMN_1,NEW_COLUMN_2,NEW_COLUMN_3,NEW_COLUMN_4)
正如我所说,我是R的新手并且不知道如何开始,所以我很感激您提供的任何帮助。
编辑:
我上面的问题除了创建新列之外,还有如何用上面一行Y列的值填充这些新列。 @CPak以非常有效的方式解决了这个问题(见下文)。
因为返回值是基于术语&#34;函数(i)dplyr :: lag(DATA $ Y,i)&#34;,我对该术语是否可以被计算替换感兴趣。
例如,可以轻松实现为新创建的列中的每个数据点返回同一行中Y列的值除以每个新的第一个单元格上方的第一行的Y列值 - 创建列?
例如,让我们取NEW_COLUMN_1(DATA [2,3])的第一个单元格,其值应由同一行(DATA [2,2]:2)中的列Y的值给出通过NEW_COLUMN_1的第一个单元格上方的第一列中的Y列的值(DATA [1,2]:1)。由于上述情况确实很复杂,我在所有单元格的坐标下方提供:
X <- c(2010,2011,2012,2013,2014)
Y <- c(1,2,3,4,5)
NEW_COLUMN_1 <- c("NA","DATA[2,2]/DATA[1,2]","DATA[3,2]/DATA[1,2]","DATA[4,2]/DATA[1,2]","DATA[5,2]/DATA[1,2]")
NEW_COLUMN_2 <- c("NA","NA","DATA[3,2]/DATA[2,2]","DATA[4,2]/DATA[2,2]","DATA[5,2]/DATA[2,2]")
NEW_COLUMN_3 <- c("NA","NA","NA","DATA[4,2]/DATA[3,2]","DATA[5,2]/DATA[3,2]")
NEW_COLUMN_4 <- c("NA","NA","NA","NA","DATA[5,2]/DATA[4,2]")
DATA <- data.frame(X,Y,NEW_COLUMN_1,NEW_COLUMN_2,NEW_COLUMN_3,NEW_COLUMN_4)
最终结果应该产生:
X <- c(2010,2011,2012,2013,2014)
Y <- c(1,2,3,4,5)
NEW_COLUMN_1 <- c(NA,2,3,4,5)
NEW_COLUMN_2 <- c(NA,NA,1.5,2,2.5)
NEW_COLUMN_3 <- c(NA,NA,NA,1.33,1.67)
NEW_COLUMN_4 <- c(NA,NA,NA,NA,1.25)
DATA <- data.frame(X,Y,NEW_COLUMN_1,NEW_COLUMN_2,NEW_COLUMN_3,NEW_COLUMN_4)
非常感谢你的帮助!
答案 0 :(得分:1)
您可以使用lapply
和dplyr::lag
创建新列。生成的列表使用Reduce("cbind", ...)
绑定在一起并转换为data.frame / tibble,并使用setNames
library(tidyverse)
newcols <- Reduce("cbind", lapply(1:(nrow(DATA)-1), function(i) dplyr::lag(DATA$Y, i))) %>%
as_tibble() %>%
setNames(paste0("NEW_COLUMN_", 1:ncol(.)))
cbind(DATA, newcols)
# X Y NEW_COLUMN_1 NEW_COLUMN_2 NEW_COLUMN_3 NEW_COLUMN_4
# 1 2010 1 NA NA NA NA
# 2 2011 2 1 NA NA NA
# 3 2012 3 2 1 NA NA
# 4 2013 4 3 2 1 NA
# 5 2014 5 4 3 2 1