如何 subset/split 由 R 中可用的常用值数组成的多列数据框
How to subset/split a dataframe of multiple columns by common number of values available in R
我有一个包含 4000 多列的数据框。并且列显示股票数据并具有缺失值。数据框有各种缺失值,因为数据框有目前在证券交易所 listed/trading 的公司以及过去在证券交易所交易的公司。如果 A 公司有 2000 年的收盘价数据,但 B 公司可能没有 2000 年的任何数据,因为 B 公司在 2000 年没有 trading/listed,因此缺少值。这使得我的数据框变得非常复杂,并且由于缺少数据而难以 运行 模型(例如自回归)。所以,我想 split/subset 这个数据框基于它们(列)之间的共同缺失值,然后删除 NA 和 运行 模型。我将数据和所需的输出说明如下
df
DATE A B C D E F G H
31/12/1999 79.5 NA NA 36.7 3 6 NA NA
03/01/2000 79.5 NA NA 36.7 3 6 NA NA
04/01/2000 79.5 NA 325 36.7 3 6 961 3081.9
05/01/2000 79.5 NA 322.5 38.8 3 6 945 2524.7
06/01/2000 79.5 NA 327.5 20.3 3 6 952 3272.3
07/01/2000 79.5 NA 327.5 15.6 3 6 941 2102.9
10/01/2000 79.5 7 327.5 5.4 3 6 946 2901.5
11/01/2000 79.5 7 327.5 15 3 6 888 9442.5
12/01/2000 79.5 7 331.5 9.3 3 6 870 7865.8
13/01/2000 79.5 7 334 29.1 3 6 853 7742.1
我想要如下数据框:
d1<-df
DATE A D E F
31/12/1999 79.5 36.7 3 6
03/01/2000 79.5 36.7 3 6
04/01/2000 79.5 36.7 3 6
05/01/2000 79.5 38.8 3 6
06/01/2000 79.5 20.3 3 6
07/01/2000 79.5 15.6 3 6
10/01/2000 79.5 5.4 3 6
11/01/2000 79.5 15 3 6
12/01/2000 79.5 9.3 3 6
13/01/2000 79.5 29.1 3 6
df2<- df
DATE C G H
31/12/1999 NA NA NA
03/01/2000 NA NA NA
04/01/2000 325 961 3081.9
05/01/2000 322.5 945 2524.7
06/01/2000 327.5 952 3272.3
07/01/2000 327.5 941 2102.9
10/01/2000 327.5 946 2901.5
11/01/2000 327.5 888 9442.5
12/01/2000 331.5 870 7865.8
13/01/2000 334 853 7742.1
df3 <- df
DATE B
31/12/1999 NA
03/01/2000 NA
04/01/2000 NA
05/01/2000 NA
06/01/2000 NA
07/01/2000 NA
10/01/2000 7
11/01/2000 7
12/01/2000 7
13/01/2000 7
非常感谢你在这方面的帮助。
使用 data.table
包将整个东西变成 data.table。
然后使用 data.table[]
的第一个参数对您的列和行进行子集化。
例如 dt[!is.na(A) & !is.na(D) & !is.na(E) & !is.na(F), .(A,D,E,F)]
应该给你第一个 table。
您能否更明确地说明制作各种子 table 的规则?
首先使用apply计算每列中的NA数量:
gr <- apply(df ,2 ,function(x) sum(is.na(x)))
gr
DATE A B C D E F G H
0 0 6 2 0 0 0 2 2
现在您可以对 data.frame 进行子集化并指定阈值
你想要的输出。
df[, c("DATE",colnames(df)[gr==0]) ]
df[, c("DATE",colnames(df)[gr>0 & gr<=5 ]) ]
df[, c("DATE",colnames(df)[gr>5]) ]
这应该适用于您正在做的事情,它会生成一个数据帧列表,您可以一次将其索引到一个数据帧中:
c <- sapply(df[, 2:ncol(df)], function(x) sum(!is.na(x)))
x <- sapply(unique(c), function(x) which(x == c))
dfList <- list(); for(i in 1:length(x)) {dfList[[i]] <- df[, c(1, as.numeric(x[[i]]) + 1)]}
输出如下:
dfList
[[1]]
DATE A D E F
1 31/12/1999 79.5 36.7 3 6
2 03/01/2000 79.5 36.7 3 6
3 04/01/2000 79.5 36.7 3 6
4 05/01/2000 79.5 38.8 3 6
5 06/01/2000 79.5 20.3 3 6
6 07/01/2000 79.5 15.6 3 6
7 10/01/2000 79.5 5.4 3 6
8 11/01/2000 79.5 15.0 3 6
9 12/01/2000 79.5 9.3 3 6
10 13/01/2000 79.5 29.1 3 6
[[2]]
DATE B
1 31/12/1999 NA
2 03/01/2000 NA
3 04/01/2000 NA
4 05/01/2000 NA
5 06/01/2000 NA
6 07/01/2000 NA
7 10/01/2000 7
8 11/01/2000 7
9 12/01/2000 7
10 13/01/2000 7
[[3]]
DATE C G H
1 31/12/1999 NA NA NA
2 03/01/2000 NA NA NA
3 04/01/2000 325.0 961 3081.9
4 05/01/2000 322.5 945 2524.7
5 06/01/2000 327.5 952 3272.3
6 07/01/2000 327.5 941 2102.9
7 10/01/2000 327.5 946 2901.5
8 11/01/2000 327.5 888 9442.5
9 12/01/2000 331.5 870 7865.8
10 13/01/2000 334.0 853 7742.1
要从上面数据框列表中的每个数据框中只检索完整的案例,您可以这样做:
dfList <- sapply(dfList, function(x) x[complete.cases(x), ])
结果输出将是本例中三个数据框的以下列表:
[[1]]
DATE A D E F
1 31/12/1999 79.5 36.7 3 6
2 03/01/2000 79.5 36.7 3 6
3 04/01/2000 79.5 36.7 3 6
4 05/01/2000 79.5 38.8 3 6
5 06/01/2000 79.5 20.3 3 6
6 07/01/2000 79.5 15.6 3 6
7 10/01/2000 79.5 5.4 3 6
8 11/01/2000 79.5 15.0 3 6
9 12/01/2000 79.5 9.3 3 6
10 13/01/2000 79.5 29.1 3 6
[[2]]
DATE B
7 10/01/2000 7
8 11/01/2000 7
9 12/01/2000 7
10 13/01/2000 7
[[3]]
DATE C G H
3 04/01/2000 325.0 961 3081.9
4 05/01/2000 322.5 945 2524.7
5 06/01/2000 327.5 952 3272.3
6 07/01/2000 327.5 941 2102.9
7 10/01/2000 327.5 946 2901.5
8 11/01/2000 327.5 888 9442.5
9 12/01/2000 331.5 870 7865.8
10 13/01/2000 334.0 853 7742.1
您可以按如下方式访问每个数据帧:
for (i in 1:lenght(dfList)) {dfList[[i]]}
还有一个解决方案:)
# always give reproducible example
df <- data.frame(A=LETTERS[1:10],
B=c(rep(NA, 8), 1:2),
C=c(rep(NA, 6), 1:4),
D=c(rep(NA, 6), 5:8))
# get indices of NAs in each column
l <- lapply(df, function(i) which(is.na(i)))
# create factors to group columns with identical NA indices
# this is stupid and could be inefficient for data.frames with lots of NA values in columns
f <- factor(sapply(l, paste, collapse=","))
# split initial data.frame on a list of data.frames
list_of_dfs <- lapply(levels(f), function(fl) df[, which(f == fl), drop = FALSE])
我有一个包含 4000 多列的数据框。并且列显示股票数据并具有缺失值。数据框有各种缺失值,因为数据框有目前在证券交易所 listed/trading 的公司以及过去在证券交易所交易的公司。如果 A 公司有 2000 年的收盘价数据,但 B 公司可能没有 2000 年的任何数据,因为 B 公司在 2000 年没有 trading/listed,因此缺少值。这使得我的数据框变得非常复杂,并且由于缺少数据而难以 运行 模型(例如自回归)。所以,我想 split/subset 这个数据框基于它们(列)之间的共同缺失值,然后删除 NA 和 运行 模型。我将数据和所需的输出说明如下
df
DATE A B C D E F G H
31/12/1999 79.5 NA NA 36.7 3 6 NA NA
03/01/2000 79.5 NA NA 36.7 3 6 NA NA
04/01/2000 79.5 NA 325 36.7 3 6 961 3081.9
05/01/2000 79.5 NA 322.5 38.8 3 6 945 2524.7
06/01/2000 79.5 NA 327.5 20.3 3 6 952 3272.3
07/01/2000 79.5 NA 327.5 15.6 3 6 941 2102.9
10/01/2000 79.5 7 327.5 5.4 3 6 946 2901.5
11/01/2000 79.5 7 327.5 15 3 6 888 9442.5
12/01/2000 79.5 7 331.5 9.3 3 6 870 7865.8
13/01/2000 79.5 7 334 29.1 3 6 853 7742.1
我想要如下数据框:
d1<-df
DATE A D E F
31/12/1999 79.5 36.7 3 6
03/01/2000 79.5 36.7 3 6
04/01/2000 79.5 36.7 3 6
05/01/2000 79.5 38.8 3 6
06/01/2000 79.5 20.3 3 6
07/01/2000 79.5 15.6 3 6
10/01/2000 79.5 5.4 3 6
11/01/2000 79.5 15 3 6
12/01/2000 79.5 9.3 3 6
13/01/2000 79.5 29.1 3 6
df2<- df
DATE C G H
31/12/1999 NA NA NA
03/01/2000 NA NA NA
04/01/2000 325 961 3081.9
05/01/2000 322.5 945 2524.7
06/01/2000 327.5 952 3272.3
07/01/2000 327.5 941 2102.9
10/01/2000 327.5 946 2901.5
11/01/2000 327.5 888 9442.5
12/01/2000 331.5 870 7865.8
13/01/2000 334 853 7742.1
df3 <- df
DATE B
31/12/1999 NA
03/01/2000 NA
04/01/2000 NA
05/01/2000 NA
06/01/2000 NA
07/01/2000 NA
10/01/2000 7
11/01/2000 7
12/01/2000 7
13/01/2000 7
非常感谢你在这方面的帮助。
使用 data.table
包将整个东西变成 data.table。
然后使用 data.table[]
的第一个参数对您的列和行进行子集化。
例如 dt[!is.na(A) & !is.na(D) & !is.na(E) & !is.na(F), .(A,D,E,F)]
应该给你第一个 table。
您能否更明确地说明制作各种子 table 的规则?
首先使用apply计算每列中的NA数量:
gr <- apply(df ,2 ,function(x) sum(is.na(x)))
gr
DATE A B C D E F G H
0 0 6 2 0 0 0 2 2
现在您可以对 data.frame 进行子集化并指定阈值 你想要的输出。
df[, c("DATE",colnames(df)[gr==0]) ]
df[, c("DATE",colnames(df)[gr>0 & gr<=5 ]) ]
df[, c("DATE",colnames(df)[gr>5]) ]
这应该适用于您正在做的事情,它会生成一个数据帧列表,您可以一次将其索引到一个数据帧中:
c <- sapply(df[, 2:ncol(df)], function(x) sum(!is.na(x)))
x <- sapply(unique(c), function(x) which(x == c))
dfList <- list(); for(i in 1:length(x)) {dfList[[i]] <- df[, c(1, as.numeric(x[[i]]) + 1)]}
输出如下:
dfList
[[1]]
DATE A D E F
1 31/12/1999 79.5 36.7 3 6
2 03/01/2000 79.5 36.7 3 6
3 04/01/2000 79.5 36.7 3 6
4 05/01/2000 79.5 38.8 3 6
5 06/01/2000 79.5 20.3 3 6
6 07/01/2000 79.5 15.6 3 6
7 10/01/2000 79.5 5.4 3 6
8 11/01/2000 79.5 15.0 3 6
9 12/01/2000 79.5 9.3 3 6
10 13/01/2000 79.5 29.1 3 6
[[2]]
DATE B
1 31/12/1999 NA
2 03/01/2000 NA
3 04/01/2000 NA
4 05/01/2000 NA
5 06/01/2000 NA
6 07/01/2000 NA
7 10/01/2000 7
8 11/01/2000 7
9 12/01/2000 7
10 13/01/2000 7
[[3]]
DATE C G H
1 31/12/1999 NA NA NA
2 03/01/2000 NA NA NA
3 04/01/2000 325.0 961 3081.9
4 05/01/2000 322.5 945 2524.7
5 06/01/2000 327.5 952 3272.3
6 07/01/2000 327.5 941 2102.9
7 10/01/2000 327.5 946 2901.5
8 11/01/2000 327.5 888 9442.5
9 12/01/2000 331.5 870 7865.8
10 13/01/2000 334.0 853 7742.1
要从上面数据框列表中的每个数据框中只检索完整的案例,您可以这样做:
dfList <- sapply(dfList, function(x) x[complete.cases(x), ])
结果输出将是本例中三个数据框的以下列表:
[[1]]
DATE A D E F
1 31/12/1999 79.5 36.7 3 6
2 03/01/2000 79.5 36.7 3 6
3 04/01/2000 79.5 36.7 3 6
4 05/01/2000 79.5 38.8 3 6
5 06/01/2000 79.5 20.3 3 6
6 07/01/2000 79.5 15.6 3 6
7 10/01/2000 79.5 5.4 3 6
8 11/01/2000 79.5 15.0 3 6
9 12/01/2000 79.5 9.3 3 6
10 13/01/2000 79.5 29.1 3 6
[[2]]
DATE B
7 10/01/2000 7
8 11/01/2000 7
9 12/01/2000 7
10 13/01/2000 7
[[3]]
DATE C G H
3 04/01/2000 325.0 961 3081.9
4 05/01/2000 322.5 945 2524.7
5 06/01/2000 327.5 952 3272.3
6 07/01/2000 327.5 941 2102.9
7 10/01/2000 327.5 946 2901.5
8 11/01/2000 327.5 888 9442.5
9 12/01/2000 331.5 870 7865.8
10 13/01/2000 334.0 853 7742.1
您可以按如下方式访问每个数据帧:
for (i in 1:lenght(dfList)) {dfList[[i]]}
还有一个解决方案:)
# always give reproducible example
df <- data.frame(A=LETTERS[1:10],
B=c(rep(NA, 8), 1:2),
C=c(rep(NA, 6), 1:4),
D=c(rep(NA, 6), 5:8))
# get indices of NAs in each column
l <- lapply(df, function(i) which(is.na(i)))
# create factors to group columns with identical NA indices
# this is stupid and could be inefficient for data.frames with lots of NA values in columns
f <- factor(sapply(l, paste, collapse=","))
# split initial data.frame on a list of data.frames
list_of_dfs <- lapply(levels(f), function(fl) df[, which(f == fl), drop = FALSE])