R语言 对列求和,直到相邻列中的单元格为NA,然后将每一列除以前一列[已解决]

rryofs0p  于 2023-06-19  发布在  其他
关注(0)|答案(2)|浏览(137)

我试图在数据表中添加列,直到相邻列的值为NA。例如,如果我有一张table:
| 日期|1| 2| 3|
| - -----|- -----|- -----|- -----|
| 2019 - 01 - 21 10:00:00| 2|十二岁|十二岁|
| 2019 - 01 - 21 10:00:00| 1| 1|不适用|
| 2019 - 01 - 29 10:00:00| 3|不适用|不适用|
我只加到第1列的第2行,因为第2列的第3行是NA,第2列的第1行是NA。然后我将每一列除以前一列。我也想忽略约会。有没有办法做到这一点,而不需要硬编码?这将是期望的结束行:
| 总计|3|十二岁|十二岁|
| - -----|- -----|- -----|- -----|
我试着使用“adorn_table”并排除NA,但似乎没有做到这一点。

hgncfbus

hgncfbus1#

对于最初的问题,尝试:

library(tidyverse)

# create made-up data
df <- tibble(
  x = c(2, 1, 3),
  y = c(12, 1, NA)
)

df |>
  filter(cumsum(is.na(y)) == 0) |>  # This will get rid of all rows starting from the first time when y is NA
  summarize(                        # add up the values of x
    s = sum(x)
  ) |>
  pull(s)

对于澄清的问题,我假设列的数量是任意的。

library(tidyverse)

# create a function to do the work
f <- function(.x, .y) {
  keep_rows <- cumsum(is.na(.y)) == 0
  sum(.x[keep_rows])
}

# create made-up data
df <- tibble(
  date = 1:3, # dates in your case, I'm keeping it simple
  x = c(2, 1, 3),
  y = c(12, 1, NA),
  z = c(12, NA, NA)
)

total_row <- map2(
 df |> select(x:z),  # select the columns being summed
 df |> select(y, z1 = z, z2 = z), # If you want the last column to depend on itself, you'll need to do something like this
  f
)

bind_rows(df |>
  mutate(date = as.character(date)), 
  c(date = "Total", total_row)
)
cigdeys3

cigdeys32#

**1)**定义一个函数sumToNA,它将x与y中第一个NA之前的位置相加。如果不存在NA,则其和X完全。

然后将该函数Map到不带列1的DF和不带前两列但最后一列的DF两次。未使用任何包。

sumToNA <- function(x, y) sum(x[!cummax(is.na(y))], na.rm = TRUE)
n <- ncol(DF)
rbind(DF, c("Total", mapply(sumToNA, DF[2:n], DF[c(3:n, n)])))
##         DATE 1    2    3
## 1 07/01/2022 2   12   12
## 2 08/01/2022 1    1 <NA>
## 3 09/01/2022 3 <NA> <NA>
## 4      Total 3   12   12

**2)**定义一个函数NAfwd,该函数接受一个向量并返回它,但在第一个NA之后包含所有NA,并将所有剩余的非NA转换为0。然后,在用NAfwd变换每列后,将DF[-1]添加到处理过的DF中,不包括前两列和最后一列两次。然后使用rowSums对其中的行求和,并将结果作为新行插入。

NAfwd <- \(z) 0 * Reduce(\(x, y) if (is.na(x)) x else y, z, acc = TRUE)

n <- ncol(DF)
rbind(DF, c("Total", colSums(DF[-1] + apply(DF[c(3:n,n)], 2, NAfwd), na.rm=TRUE)))
##         DATE 1    2    3
## 1 07/01/2022 2   12   12
## 2 08/01/2022 1    1 <NA>
## 3 09/01/2022 3 <NA> <NA>
## 4      Total 3   12   12

注意事项

DF <- data.frame(
  DATE = c("07/01/2022", "08/01/2022", "09/01/2022"),
  `1` = c(2L, 1L, 3L),
  `2` = c(12L, 1L, NA),
  `3` = c(12L, NA, NA),
  check.names = FALSE
)

相关问题