在列中填充缺失值,然后过滤
Fill missing values in column and then filter
我正在抓取一些 PDF 数据,在我准备好进入下一步之前需要注意一下。列 x1 是唯一 ID,然后 x2 是获取类型。我需要跨这些类型复制 UID,以便我可以根据类型进行过滤。下面是一些示例数据以及我想要得到的数据。我现在对 type4 特别感兴趣,但以后可能需要其他类型。
我没有尝试过的代码,因为我不确定如何解决这个问题。获取类型是一致的——在示例数据中,总是有 4 种类型,并且 UID 确实出现在 x1 和 x2 列中。
数据如何读入 R:
df <- data.frame(x1 = c(100, "", "", "", "", 101, "", "", "", "", 102, "", "", "", ""),
x2 = c(100, "type1", "type2", "type3", "type4", 101, "type1", "type2", "type3", "type4", 102, "type1", "type2", "type3", "type4"),
x3 = c(1:15),
x4 = c(31:45),
x5 = c(100:114))
x1 x2 x3 x4 x5
1 100 100 1 31 100
2 type1 2 32 101
3 type2 3 33 102
4 type3 4 34 103
5 type4 5 35 104
6 101 101 6 36 105
7 type1 7 37 106
8 type2 8 38 107
9 type3 9 39 108
10 type4 10 40 109
11 102 102 11 41 110
12 type1 12 42 111
13 type2 13 43 112
14 type3 14 44 113
15 type4 15 45 114
所需数据
goal <- data.frame(x1 = c(100, 101, 102),
x2 = c("type4", "type4", "type4"),
x3 = c(5, 10, 15),
x4 = c(35, 40, 45),
x5 = c(104, 109, 114))
x1 x2 x3 x4 x5
1 100 type4 5 35 104
2 101 type4 10 40 109
3 102 type4 15 45 114
我也愿意用不同的方法来解决这个问题,但是复制 UID 直到有一个新的 UID 是我认为最好的方法。
按要求 - 先填充,再过滤...
这仅使用 tidyverse
。我先把空字符串""换成了NA.
library(tidyverse)
df <- data.frame(x1 = c(100, "", "", "", "", 101, "", "", "", "", 102, "", "", "", ""),
x2 = c(100, "type1", "type2", "type3", "type4", 101, "type1", "type2", "type3", "type4", 102, "type1", "type2", "type3", "type4"),
x3 = c(1:15),
x4 = c(31:45),
x5 = c(100:114))
df %>%
mutate(x1 = as.integer(x1)) %>%
fill(x1) %>%
filter(x2 == "type4")
#> x1 x2 x3 x4 x5
#> 1 100 type4 5 35 104
#> 2 101 type4 10 40 109
#> 3 102 type4 15 45 114
另一种方法利用数据的明显有序且规则的结构:(在此示例中仅使用基数 R)
x1 <- na.omit(as.integer(df$x1))
df2 <- subset(df, x2 == "type4")
df2$x1 <- x1
df2
#> x1 x2 x3 x4 x5
#> 5 100 type4 5 35 104
#> 10 101 type4 10 40 109
#> 15 102 type4 15 45 114
使用 by
拆分合并。使用 transform
.
回收 x1 的第一个元素
res <- `rownames<-`(do.call(rbind, by(df, rep(1:(nrow(df)/5), each=5), function(x) {
transform(x, x1=x1[1])
})), NULL)
res
# x1 x2 x3 x4 x5
# 1 100 100 1 31 100
# 2 100 type1 2 32 101
# 3 100 type2 3 33 102
# 4 100 type3 4 34 103
# 5 100 type4 5 35 104
# 6 101 101 6 36 105
# 7 101 type1 7 37 106
# 8 101 type2 8 38 107
# 9 101 type3 9 39 108
# 10 101 type4 10 40 109
# 11 102 102 11 41 110
# 12 102 type1 12 42 111
# 13 102 type2 13 43 112
# 14 102 type3 14 44 113
# 15 102 type4 15 45 114
然后随意筛选。
res[res$x2 %in% "type4", ]
# x1 x2 x3 x4 x5
# 5 100 type4 5 35 104
# 10 101 type4 10 40 109
# 15 102 type4 15 45 114
注:`rownames<-`(..., NULL)
只是装饰品,你也可以不加。
我正在抓取一些 PDF 数据,在我准备好进入下一步之前需要注意一下。列 x1 是唯一 ID,然后 x2 是获取类型。我需要跨这些类型复制 UID,以便我可以根据类型进行过滤。下面是一些示例数据以及我想要得到的数据。我现在对 type4 特别感兴趣,但以后可能需要其他类型。
我没有尝试过的代码,因为我不确定如何解决这个问题。获取类型是一致的——在示例数据中,总是有 4 种类型,并且 UID 确实出现在 x1 和 x2 列中。
数据如何读入 R:
df <- data.frame(x1 = c(100, "", "", "", "", 101, "", "", "", "", 102, "", "", "", ""),
x2 = c(100, "type1", "type2", "type3", "type4", 101, "type1", "type2", "type3", "type4", 102, "type1", "type2", "type3", "type4"),
x3 = c(1:15),
x4 = c(31:45),
x5 = c(100:114))
x1 x2 x3 x4 x5
1 100 100 1 31 100
2 type1 2 32 101
3 type2 3 33 102
4 type3 4 34 103
5 type4 5 35 104
6 101 101 6 36 105
7 type1 7 37 106
8 type2 8 38 107
9 type3 9 39 108
10 type4 10 40 109
11 102 102 11 41 110
12 type1 12 42 111
13 type2 13 43 112
14 type3 14 44 113
15 type4 15 45 114
所需数据
goal <- data.frame(x1 = c(100, 101, 102),
x2 = c("type4", "type4", "type4"),
x3 = c(5, 10, 15),
x4 = c(35, 40, 45),
x5 = c(104, 109, 114))
x1 x2 x3 x4 x5
1 100 type4 5 35 104
2 101 type4 10 40 109
3 102 type4 15 45 114
我也愿意用不同的方法来解决这个问题,但是复制 UID 直到有一个新的 UID 是我认为最好的方法。
按要求 - 先填充,再过滤...
这仅使用 tidyverse
。我先把空字符串""换成了NA.
library(tidyverse)
df <- data.frame(x1 = c(100, "", "", "", "", 101, "", "", "", "", 102, "", "", "", ""),
x2 = c(100, "type1", "type2", "type3", "type4", 101, "type1", "type2", "type3", "type4", 102, "type1", "type2", "type3", "type4"),
x3 = c(1:15),
x4 = c(31:45),
x5 = c(100:114))
df %>%
mutate(x1 = as.integer(x1)) %>%
fill(x1) %>%
filter(x2 == "type4")
#> x1 x2 x3 x4 x5
#> 1 100 type4 5 35 104
#> 2 101 type4 10 40 109
#> 3 102 type4 15 45 114
另一种方法利用数据的明显有序且规则的结构:(在此示例中仅使用基数 R)
x1 <- na.omit(as.integer(df$x1))
df2 <- subset(df, x2 == "type4")
df2$x1 <- x1
df2
#> x1 x2 x3 x4 x5
#> 5 100 type4 5 35 104
#> 10 101 type4 10 40 109
#> 15 102 type4 15 45 114
使用 by
拆分合并。使用 transform
.
res <- `rownames<-`(do.call(rbind, by(df, rep(1:(nrow(df)/5), each=5), function(x) {
transform(x, x1=x1[1])
})), NULL)
res
# x1 x2 x3 x4 x5
# 1 100 100 1 31 100
# 2 100 type1 2 32 101
# 3 100 type2 3 33 102
# 4 100 type3 4 34 103
# 5 100 type4 5 35 104
# 6 101 101 6 36 105
# 7 101 type1 7 37 106
# 8 101 type2 8 38 107
# 9 101 type3 9 39 108
# 10 101 type4 10 40 109
# 11 102 102 11 41 110
# 12 102 type1 12 42 111
# 13 102 type2 13 43 112
# 14 102 type3 14 44 113
# 15 102 type4 15 45 114
然后随意筛选。
res[res$x2 %in% "type4", ]
# x1 x2 x3 x4 x5
# 5 100 type4 5 35 104
# 10 101 type4 10 40 109
# 15 102 type4 15 45 114
注:`rownames<-`(..., NULL)
只是装饰品,你也可以不加。