我有一个类似矩阵的数据框,附加一列表示时间。它包含有关特定学校注册学生人数的信息,从5年级(A
栏)到9年级(E
栏)。
time A B C D E
1 13 1842 1844 1689 1776 1716
2 14 1898 1785 1807 1617 1679
3 15 2065 1865 1748 1731 1590
4 16 2215 1994 1811 1708 1703
5 17 2174 2122 1903 1765 1699
我需要随着时间的推移追踪队列的大小,这意味着我需要从6到9年级开始每年有多少五年级学生留在学校的行数信息。例如,对于那个队列2013年开始上五年级,我想了解2014年六年级中剩下多少人的信息,等等。
预期输出
这就是我想要的结果:
start.time point.A point.B point.C point.D point.E
1 13 1842 1785 1748 1708 1699
2 14 1898 1865 1811 1765 NA
3 15 2065 1811 1765 NA NA
4 16 2215 1765 NA NA NA
5 17 2174 NA NA NA NA
我从diag()
查看base.R
,但我只能从主对角线获取数据。理想情况下,我想使用dplyr
语法和管道来完成此任务。
数据
structure(list(time = 13:17, A = c(1842, 1898, 2065, 2215, 2174), B = c(1844, 1785, 1865, 1994, 2122), C = c(1689, 1807, 1748, 1811, 1903), D = c(1776, 1617, 1731, 1708, 1765), E = c(1716, 1679, 1590, 1703, 1699)), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, -5L), vars = "time", drop = TRUE, indices = list(
0L, 1L, 2L, 3L, 4L), group_sizes = c(1L, 1L, 1L, 1L, 1L), biggest_group_size = 1L, labels = structure(list(
time = 13:17), class = "data.frame", row.names = c(NA, -5L), vars = "time", drop = TRUE, .Names = "time"), .Names = c("time", "A", "B", "C", "D", "E"))
答案 0 :(得分:5)
将第一列以外的输入DF
转换为矩阵mat
。然后,由于row(mat) - col(mat)
在对角线split
上相对于ts
在L
中创建ts
类序列列表而言是恒定的。我们使用cbind
类,因为我们可以稍后row(mat) - col(mat) >= 0
使用它们,即使它们的长度不同。对象cbind
是我们想要的唯一对象,所以将它们DF
组合在一起并转换结果。然后替换mat <- as.matrix(DF[-1])
L <- lapply(split(mat, row(mat) - col(mat)), ts)
replace(DF, -1, t(do.call("cbind", L[as.numeric(names(L)) >= 0])))
中的所有列,除了第一列。没有包使用。
time A B C D E
1 13 1842 1785 1748 1708 1699
2 14 1898 1865 1811 1765 NA
3 15 2065 1994 1903 NA NA
4 16 2215 2122 NA NA NA
5 17 2174 NA NA NA NA
,并提供:
#include <iostream>
#include <string>
template<int T, int U>
void foo(T a, U b)
{
std::cout << a+b << std::endl;
}
int main() {
foo(2,4);
return 0;
}
答案 1 :(得分:2)
由于您在问题中提及了dplyr
,因此您可以使用dplyr::lead
将列B
的值分别转换为E
1,2等。然后将结果与原始数据中的列time
和A
绑定,如下所示
library(tidyverse)
bind_cols(df[, 1:2], map2_df(.x = df[, c(3:ncol(df))],
.y = seq_along(df[, 3:ncol(df)]),
.f = ~dplyr::lead(x = .x, n = .y)))
# A tibble: 5 x 6
# Groups: time [5]
# time A B C D E
# <int> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 13 1842 1785 1748 1708 1699
#2 14 1898 1865 1811 1765 NA
#3 15 2065 1994 1903 NA NA
#4 16 2215 2122 NA NA NA
#5 17 2174 NA NA NA NA
请注意,您的数据按照您提供的方式按time
分组。
答案 2 :(得分:1)
通过一些分组和整理以及row_number()
,我们可以使用dplyr
和tidyr
执行此操作,并且我们不会丢失值。
看起来有点乱,但在这里我创建了一个二维索引,其中第二个维度被反转。当这些索引位置相加时,我们得到对角行的匹配值。
data %>%
ungroup() %>%
mutate(row = row_number()) %>%
gather(class, stud, A:E) %>%
arrange(row, desc(class)) %>%
group_by(row) %>%
mutate(time_left = row_number()) %>%
ungroup() %>%
transmute(time, class, stud, start_year = time_left + row - 1) %>%
ggplot(aes(time, stud, color = factor(start_year))) +
geom_line() +
geom_point()
答案 3 :(得分:0)
替换&#34; d&#34;的镜像上三角形。使用下三角形的值。
m <- as.matrix(d[-1])
d[-1] <- NA
d[-1][upper.tri(m, diag = TRUE)[ , ncol(m):1]] <- m[lower.tri(m, diag = TRUE)]
# time A B C D E
# 1 13 1842 1785 1748 1708 1699
# 2 14 1898 1865 1811 1765 NA
# 3 15 2065 1994 1903 NA NA
# 4 16 2215 2122 NA NA NA
# 5 17 2174 NA NA NA NA