我想从不同的数据帧合并19个不同长度的列并进行比较。这是一个例子:
df1:
PA0001
PA0002
PA0003
PA0004
PA0005
df2:
PA0001
PA0003
PA0006
PA0007
df3:
PA0001
PA0007
等...
输出就是这样的:
PA0001 | PA0001 | PA0001
PA0002 | NA | NA
PA0003 | PA0003 | NA
PA0004 | NA | NA
PA0005 | NA | NA
NA | PA0006 | NA
NA | PA0007 | PA0007
我使用compare
或merge
功能,但我的效果不佳。我试图使用这个问题的功能:Link
但我收到了这个错误:
Error in attributes(.Data) <- c(attributes(.Data), attrib) :
'names' attribute [5254] must be the same length as the vector [2]
以下是您的例子:
test1 <- data.frame(c("PA0001","PA0002","PA0003","PA0004","PA0005","PA0006"))
test2 <- data.frame(c("PA0001","PA0002","PA0004","PA0005","PA0007"))
test3 <- data.frame(c("PA0001","PA0004","PA0005","PA0007", "PA0008"))
非常感谢你。
答案 0 :(得分:6)
如果我们需要OP中预期的输出,请将数据集放在list
中,然后在创建&#39; grp&#39;之前绑定list
元素。列rbindlist
,dcast
来自&#39; long&#39;广泛的&#39;通过match
&#39; id&#39;在公式中创建序列列使用unique
元素&#39; id&#39;
library(data.table)
dcast(rbindlist(list(test1, test2, test3), idcol = 'grp'),
match(id, unique(id)) ~ paste0("col", grp))[, id := NULL][]
# col1 col2 col3
#1: PA0001 PA0001 PA0001
#2: PA0002 NA NA
#3: PA0003 PA0003 NA
#4: PA0004 NA NA
#5: PA0005 NA NA
#6: NA PA0006 NA
#7: NA PA0007 PA0007
或者@jogo分割代码,以便在第一步中rbind
创建&#39; grp&#39;时list
idcol
中的所有数据集。列通过指定t_all <- rbindlist(list(test1, test2, test3), idcol='grp');
参数
dcast
然后NULL
,广泛&#39;格式并指定“id”#39;列到dcast(t_all, id ~ grp, value.var='id')[, id := NULL][]
test1 <- data.frame(id = c("PA0001","PA0002","PA0003","PA0004","PA0005"))
test2 <- data.frame(id = c("PA0001","PA0003","PA0006","PA0007"))
test3 <- data.frame(id = c("PA0001", "PA0007"))
{% extends "music/base.html" %}
{% block body %}
{% load staticfiles %}
<img src="{% static 'music/image/Robot-PNG-File.png' %}" class="rounded-circle" alt="face" style='max-height:200px'><br>
<h2>{{album.album_title}}</h2>
<h3>{{album.artist}}</h3>
<ul>
{% for songs in album.song_set.all%}
<li>{{songs.song_title}}- {{songs.file_type}}</li>
{% endfor %}<br>
</ul>
{% endblock %}
答案 1 :(得分:5)
您可以尝试tidyverse
解决方案
library(tidyverse)
d1 <- read.table(text="PA0001
PA0002
PA0003
PA0004
PA0005")
d2 <- read.table(text="PA0001
PA0003
PA0006
PA0007")
d3 <- read.table(text="PA0001
PA0007")
list(d1, d2, d3) %>%
bind_rows(.id = "df") %>%
mutate(n = TRUE) %>%
spread(df, n, fill = FALSE)
V1 1 2 3
1 PA0001 TRUE TRUE TRUE
2 PA0002 TRUE FALSE FALSE
3 PA0003 TRUE TRUE FALSE
4 PA0004 TRUE FALSE FALSE
5 PA0005 TRUE FALSE FALSE
6 PA0006 FALSE TRUE FALSE
7 PA0007 FALSE TRUE TRUE
我们的想法是将所有data.frame包含在列表中,然后按行绑定它们,添加逻辑TRUE并使用tidyr
的{{1}}函数来获取结果。
当然,你也可以使用以下方法获得你的输出:
spread
在list(d1, d2, d3) %>%
bind_rows(.id="df") %>%
mutate(n=V1) %>%
spread(df, n) %>%
select(-1)
1 2 3
1 PA0001 PA0001 PA0001
2 PA0002 <NA> <NA>
3 PA0003 PA0003 <NA>
4 PA0004 <NA> <NA>
5 PA0005 <NA> <NA>
6 <NA> PA0006 <NA>
7 <NA> PA0007 PA000
R中,您可以尝试:
base
答案 2 :(得分:2)
以下是基础R解决方案:
x <- lapply(list(test1, test2, test3), function(x) as.character(x[,1]))
xuni <- unique(unlist(x))
one_set <- function(i) {
idx <- which(is.na(match(xuni, x[[i]])))
ans <- xuni
ans[idx] <- NA
return(ans)
}
res <- data.frame(
test1=one_set(1),
test2=one_set(2),
test3=one_set(3),
stringsAsFactors=FALSE
)
res
test1 test2 test3
1 PA0001 PA0001 PA0001
2 PA0002 PA0002 <NA>
3 PA0003 <NA> <NA>
4 PA0004 PA0004 PA0004
5 PA0005 PA0005 PA0005
6 PA0006 <NA> <NA>
7 <NA> PA0007 PA0007
8 <NA> <NA> PA0008
第一行将因子转换为字符,并将data.frame转换为每个data.frame中元素的列表x
。
第二行标识所有观察到的值。
函数one_set
接受一个索引(要查看x
的元素)并返回所需的输出列。