如何将每列中的字符转换为不重复的总和列
how to covert character within each column as sub-column without duplication
我有一个这样的 data.frame 文件:
输入:
1 200 444 444
2 310 NA 444
3 310 NA 444
4 NA 444 444
5 200 444 444
6 200 NA 444
7 310 444 444
8 310 876 444
9 310 876 444
10 NA 876 444
我想将每一列中的 ecah 字符转换为子列,并且我想在行中放置 1 或零,以表示是否在该特定行中观察到子列:
输出 data.frame :
c1.200 c1.310 c2.444 c2.876 c3.444
1 1 0 1 0 1
2 0 1 0 0 1
3 0 1 0 0 1
4 0 0 1 0 1
5 1 0 1 0 1
6 1 0 0 0 1
7 0 1 1 0 1
8 0 1 0 1 1
9 0 1 0 1 1
10 0 0 0 1 1
R 中是否有任何解决方案可以做到这一点?同时,我的真实数据有 117000 行和 10,000 列。
我们可以使用 dplyr
和 tidyr
:
library(dplyr)
library(tidyr)
newdat <- dat %>% setNames(paste0("c", 1:ncol(.), ".")) %>%
mutate(row = row_number(), n = 1) %>%
gather(key, val, -row, -n) %>%
na.omit %>%
unite(keyval, key, val, sep = "") %>%
spread(keyval, n, fill = 0)
row c1.200 c1.310 c2.444 c2.876 c3.444
1 1 1 0 1 0 1
2 2 0 1 0 0 1
3 3 0 1 0 0 1
4 4 0 0 1 0 1
5 5 1 0 1 0 1
6 6 1 0 0 0 1
7 7 0 1 1 0 1
8 8 0 1 0 1 1
9 9 0 1 0 1 1
10 10 0 0 0 1 1
我使用了这个数据集,因为 dat
:
structure(list(V2 = c(200L, 310L, 310L, NA, 200L, 200L, 310L,
310L, 310L, NA), V3 = c(444L, NA, NA, 444L, 444L, NA, 444L, 876L,
876L, 876L), V4 = c(444L, 444L, 444L, 444L, 444L, 444L, 444L,
444L, 444L, 444L)), .Names = c("V2", "V3", "V4"), class = "data.frame", row.names = c(NA,
-10L))
要输出,使用write.csv(newdat, file="yourfilename.csv")
我们可以使用 base R
中的 table
来做到这一点。我们 unlist
数据集 paste
的新列名称以 c
开头,使用 is.na
删除 NA
元素,得到 table
具有行序列和 paste
向量。
nm1 <- paste0('c', 1:3, '.')[col(dat)]
v1 <- unlist(dat)
i1 <- !is.na(v1)
newdat <- as.data.frame.matrix(table((1:nrow(dat))[row(dat)][i1],
paste0(nm1[i1], v1[i1])))
newdat
# c1.200 c1.310 c2.444 c2.876 c3.444
# 1 1 0 1 0 1
# 2 0 1 0 0 1
# 3 0 1 0 0 1
# 4 0 0 1 0 1
# 5 1 0 1 0 1
# 6 1 0 0 0 1
# 7 0 1 1 0 1
# 8 0 1 0 1 1
# 9 0 1 0 1 1
# 10 0 0 0 1 1
我有一个这样的 data.frame 文件: 输入:
1 200 444 444
2 310 NA 444
3 310 NA 444
4 NA 444 444
5 200 444 444
6 200 NA 444
7 310 444 444
8 310 876 444
9 310 876 444
10 NA 876 444
我想将每一列中的 ecah 字符转换为子列,并且我想在行中放置 1 或零,以表示是否在该特定行中观察到子列: 输出 data.frame :
c1.200 c1.310 c2.444 c2.876 c3.444
1 1 0 1 0 1
2 0 1 0 0 1
3 0 1 0 0 1
4 0 0 1 0 1
5 1 0 1 0 1
6 1 0 0 0 1
7 0 1 1 0 1
8 0 1 0 1 1
9 0 1 0 1 1
10 0 0 0 1 1
R 中是否有任何解决方案可以做到这一点?同时,我的真实数据有 117000 行和 10,000 列。
我们可以使用 dplyr
和 tidyr
:
library(dplyr)
library(tidyr)
newdat <- dat %>% setNames(paste0("c", 1:ncol(.), ".")) %>%
mutate(row = row_number(), n = 1) %>%
gather(key, val, -row, -n) %>%
na.omit %>%
unite(keyval, key, val, sep = "") %>%
spread(keyval, n, fill = 0)
row c1.200 c1.310 c2.444 c2.876 c3.444
1 1 1 0 1 0 1
2 2 0 1 0 0 1
3 3 0 1 0 0 1
4 4 0 0 1 0 1
5 5 1 0 1 0 1
6 6 1 0 0 0 1
7 7 0 1 1 0 1
8 8 0 1 0 1 1
9 9 0 1 0 1 1
10 10 0 0 0 1 1
我使用了这个数据集,因为 dat
:
structure(list(V2 = c(200L, 310L, 310L, NA, 200L, 200L, 310L,
310L, 310L, NA), V3 = c(444L, NA, NA, 444L, 444L, NA, 444L, 876L,
876L, 876L), V4 = c(444L, 444L, 444L, 444L, 444L, 444L, 444L,
444L, 444L, 444L)), .Names = c("V2", "V3", "V4"), class = "data.frame", row.names = c(NA,
-10L))
要输出,使用write.csv(newdat, file="yourfilename.csv")
我们可以使用 base R
中的 table
来做到这一点。我们 unlist
数据集 paste
的新列名称以 c
开头,使用 is.na
删除 NA
元素,得到 table
具有行序列和 paste
向量。
nm1 <- paste0('c', 1:3, '.')[col(dat)]
v1 <- unlist(dat)
i1 <- !is.na(v1)
newdat <- as.data.frame.matrix(table((1:nrow(dat))[row(dat)][i1],
paste0(nm1[i1], v1[i1])))
newdat
# c1.200 c1.310 c2.444 c2.876 c3.444
# 1 1 0 1 0 1
# 2 0 1 0 0 1
# 3 0 1 0 0 1
# 4 0 0 1 0 1
# 5 1 0 1 0 1
# 6 1 0 0 0 1
# 7 0 1 1 0 1
# 8 0 1 0 1 1
# 9 0 1 0 1 1
# 10 0 0 0 1 1