如何添加具有 NA 的行作为 R 中的先前列?
How do you add rows that have NA as prior columns in R?
全部,
我有一个数据框,第一列为日期,类别如下:
Accounts <- c('A','B','C','D',
'A','B','C','D',
'A','B','C','D')
Dates <- as.Date(c('2016-01-31', '2016-01-31','2016-01-31','2016-01-31',
'2016-02-28','2016-02-28','2016-02-28','2016-02-28',
'2016-03-31','2016-03-31','2016-03-31','2016-03-31'))
Balances <- c(100,NA,NA,NA,
90,50,10,NA,
80,40,5,120)
Origination <- data.frame(Dates,Accounts,Balances)
library(reshape2)
Origination <- dcast(Origination,Dates ~ Accounts, value.var = "Balances")
Dates A B C D
1 2016-01-31 100 NA NA NA
2 2016-02-28 90 50 10 NA
3 2016-03-31 80 40 5 120
目标是对先验值为 NA 的行求和。我尝试使用滞后或移位但不知道如何实现它。
所以对于这个数据框,我想要一个总计列,它在二月和三月的值为 60 (50 + 10) 和 120。
这可行吗?
此致,
阿克塞尔
将选择向下移动一行,过滤掉所有non-NA的为0,然后使用rowSums
:
sel <- rbind(FALSE, !is.na(head(Origination[-1], -1)))
#sel
# A B C D
#[1,] FALSE FALSE FALSE FALSE
#[2,] TRUE FALSE FALSE FALSE
#[3,] TRUE TRUE TRUE FALSE
rowSums(replace(Origination[-1], sel, 0), na.rm=TRUE)
#[1] 100 60 120
如果你想完全排除第一行,而不是完全包括,只需将 FALSE
更改为 TRUE
:
sel <- rbind(TRUE, !is.na(head(Origination[-1], -1)))
rowSums(replace(Origination[-1], sel, 0), na.rm=TRUE)
#[1] 0 60 120
thelatemail 的解决方案看起来很棒。
但是,如果您想避免打印 1 月份的总值,请试试这个
Origination.matrix.select<-rbind(F,is.na(Origination[-1]))[-4,]
Total<-rowSums(as.matrix(Origination[,2:5])*Origination.matrix.select,na.rm=T)
Total
# [1] 0 60 120
一种选择是继续链表 reshape2::dcast
并使用 dplyr::mutate_at
找到所需的输出。
library(tidyverse)
library(reshape2)
Origination %>%
dcast(Dates~Accounts, value.var = "Balances" ) %>%
mutate_at(vars(c("A","B","C","D")),
funs(ifelse(!is.na(lag(.)), NA, (.)))) %>%
mutate(sum = rowSums(select(.,-Dates), na.rm = TRUE)) %>%
select(Dates, sum)
# Dates sum
# 1 2016-01-31 100
# 2 2016-02-28 60
# 3 2016-03-31 120
注意:如果 January
的总和预计为 0
,则应在 mutate_at
中添加 row_number()==1
条件的一部分 ifelse
。
数据
Accounts <- c('A','B','C','D',
'A','B','C','D',
'A','B','C','D')
Dates <- as.Date(c('2016-01-31', '2016-01-31','2016-01-31','2016-01-31',
'2016-02-28','2016-02-28','2016-02-28','2016-02-28',
'2016-03-31','2016-03-31','2016-03-31','2016-03-31'))
Balances <- c(100,NA,NA,NA,
90,50,10,NA,
80,40,5,120)
Origination <- data.frame(Dates,Accounts,Balances)
全部,
我有一个数据框,第一列为日期,类别如下:
Accounts <- c('A','B','C','D',
'A','B','C','D',
'A','B','C','D')
Dates <- as.Date(c('2016-01-31', '2016-01-31','2016-01-31','2016-01-31',
'2016-02-28','2016-02-28','2016-02-28','2016-02-28',
'2016-03-31','2016-03-31','2016-03-31','2016-03-31'))
Balances <- c(100,NA,NA,NA,
90,50,10,NA,
80,40,5,120)
Origination <- data.frame(Dates,Accounts,Balances)
library(reshape2)
Origination <- dcast(Origination,Dates ~ Accounts, value.var = "Balances")
Dates A B C D
1 2016-01-31 100 NA NA NA
2 2016-02-28 90 50 10 NA
3 2016-03-31 80 40 5 120
目标是对先验值为 NA 的行求和。我尝试使用滞后或移位但不知道如何实现它。
所以对于这个数据框,我想要一个总计列,它在二月和三月的值为 60 (50 + 10) 和 120。
这可行吗?
此致, 阿克塞尔
将选择向下移动一行,过滤掉所有non-NA的为0,然后使用rowSums
:
sel <- rbind(FALSE, !is.na(head(Origination[-1], -1)))
#sel
# A B C D
#[1,] FALSE FALSE FALSE FALSE
#[2,] TRUE FALSE FALSE FALSE
#[3,] TRUE TRUE TRUE FALSE
rowSums(replace(Origination[-1], sel, 0), na.rm=TRUE)
#[1] 100 60 120
如果你想完全排除第一行,而不是完全包括,只需将 FALSE
更改为 TRUE
:
sel <- rbind(TRUE, !is.na(head(Origination[-1], -1)))
rowSums(replace(Origination[-1], sel, 0), na.rm=TRUE)
#[1] 0 60 120
thelatemail 的解决方案看起来很棒。
但是,如果您想避免打印 1 月份的总值,请试试这个
Origination.matrix.select<-rbind(F,is.na(Origination[-1]))[-4,]
Total<-rowSums(as.matrix(Origination[,2:5])*Origination.matrix.select,na.rm=T)
Total
# [1] 0 60 120
一种选择是继续链表 reshape2::dcast
并使用 dplyr::mutate_at
找到所需的输出。
library(tidyverse)
library(reshape2)
Origination %>%
dcast(Dates~Accounts, value.var = "Balances" ) %>%
mutate_at(vars(c("A","B","C","D")),
funs(ifelse(!is.na(lag(.)), NA, (.)))) %>%
mutate(sum = rowSums(select(.,-Dates), na.rm = TRUE)) %>%
select(Dates, sum)
# Dates sum
# 1 2016-01-31 100
# 2 2016-02-28 60
# 3 2016-03-31 120
注意:如果 January
的总和预计为 0
,则应在 mutate_at
中添加 row_number()==1
条件的一部分 ifelse
。
数据
Accounts <- c('A','B','C','D',
'A','B','C','D',
'A','B','C','D')
Dates <- as.Date(c('2016-01-31', '2016-01-31','2016-01-31','2016-01-31',
'2016-02-28','2016-02-28','2016-02-28','2016-02-28',
'2016-03-31','2016-03-31','2016-03-31','2016-03-31'))
Balances <- c(100,NA,NA,NA,
90,50,10,NA,
80,40,5,120)
Origination <- data.frame(Dates,Accounts,Balances)