R 如何折叠NA并将多个列合并为一列
我有一个合并的数据集,如下所示:R 如何折叠NA并将多个列合并为一列,r,merge,collapse,R,Merge,Collapse,我有一个合并的数据集,如下所示: V3 V1.x V2.x V1.y V2.y V982 V2163 1 10075 Whitten Jamie L. 1225 <NA> NA 2 2 2 10421 Yates Sidney R. 1252 Yates Sidney R. 1252 2 0
V3 V1.x V2.x V1.y V2.y V982 V2163
1 10075 Whitten Jamie L. 1225 <NA> NA 2 2
2 10421 Yates Sidney R. 1252 Yates Sidney R. 1252 2 0
3 10520 Gonzalez Henry B. 445 Gonzalez Henry B. 445 0 0
4 10573 Brown George E.Jr. 134 Brown George E.Jr. 134 0 0
5 29584 <NA> NA Cubin Barbara 254 0 0
我使用了简单的merge命令,比如merge(df1,df2,by=c(“V3”)
2) 如果没有V1.x和V1.y无法合并这两个数据集,那么如何折叠NAs并合并这两列
我在论坛中搜索了其他问题,发现了如下命令
cbind(数据[1],mycl=na.omit(未列出(数据[-1])))
na.省略(堆栈(df))
或者
df2如果我正确理解您的最终产品,使用dplyr
这将是一个简单的:
df1 %>%
select(V3, V982) %>%
left_join(select(df2,V3,V2163), by=V3)
其中:
V3 V982 V2163
1 10075 2 2
2 10421 2 0
3 10520 0 0
4 10573 0 0
5 29584 0 0
在这里,我回答第二个问题,因为您提供了合并的数据集
其思想是创建一个模式(“pat”)来指定需要折叠的列的“前缀”。使用grep
获取这些列的数字索引(“indx”)。从原始数据集(“df”)中删除列,并创建新的数据集“df1”。使用lappy
循环“pat”,使用grep
子集类似的前缀列,使用pmax
和na.rm=TRUE
获得折叠列的值,最后将列表元素分配给“df1”中的新列(“V1,V2”)
数据
df
1) 有没有什么方法可以合并两个数据集而不生成V1.x
V1.y
您可以尝试此解决方案,它将作用于df1
和df2
中存在的所有列:
d1 <- df1[df1$V3 %in% df2$V3,]
d2 <- df2[df2$V3 %in% df1$V3,]
m <- match(d2$V3,d1$V3)
z <- sapply(names(d1),function(s) ifelse(is.na(d1[,s]),d2[m,s],d1[,s]))
result <- cbind(z,d2[m,setdiff(names(d2),names(d1)),drop=F])
您的最终数据集是否应仅为V3
、V982
和V2163
?还是应该是V3
V1.x
,V1.y
,V982
和V2163
,然后是一个组合的V2.x
和V2.y
,这样其中一个的NA
与另一个的NA
一起归档?也许你想要合并(df1,df2,by=c(“V3”,“V1”)
?@MaratTalipov,这将不起作用(首先,因为您缺少一个)
,因为这样您将失去那些在V1
或V2
上拥有NA
或
的人(如果您要通过
语句将V2
添加到。@AndrewTaylor,说得好。那么,df$V1怎么样?我想他也想合并V1/V2列。看起来它只是V3My内部联接上的一个内部联接(通过dplyr::internal\u联接
)看起来就像OPs输出。我是否缺少一个会折叠V1和V2的参数?因此,这是采用已经进行的错误合并,并折叠V1s和V2s?现在请更清楚地阅读问题。是的,我采用了错误合并数据:-)这似乎是一个有点有趣的问题,而不是通常的merge
类型。因此,基本上,我是在回答第二个问题。我认为您的第一种方法删除了最后一行(我可能也错了,因为没有提供数据集)。是的,我想在真实的数据集上测试它。
pat <- paste0('^V', 1:2, '..$')
indx <- grep(paste(pat, collapse='|'), names(df))
df1 <- df[-indx]
df1[paste0('V',1:2)] <- lapply(pat, function(x) do.call(pmax,
c(df[grep(x, names(df))], na.rm=TRUE)))
df1
# V3 V982 V2163 V1 V2
#1 10075 2 2 Whitten Jamie L. 1225
#2 10421 2 0 Yates Sidney R. 1252
#3 10520 0 0 Gonzalez Henry B. 445
#4 10573 0 0 Brown George E.Jr. 134
#5 29584 0 0 Cubin Barbara 254
df1[paste0('V', 1:2)] <- lapply(pat, function(x) {
x1 <- df[grep(x, names(df))]
x1[cbind(1:nrow(x1), max.col(!is.na(x1)))]})
df <- structure(list(V3 = c(10075L, 10421L, 10520L, 10573L, 29584L),
V1.x = c("Whitten Jamie L.", "Yates Sidney R.", "Gonzalez Henry B.",
"Brown George E.Jr.", NA), V2.x = c(1225L, 1252L, 445L, 134L,
NA), V1.y = c(NA, "Yates Sidney R.", "Gonzalez Henry B.",
"Brown George E.Jr.", "Cubin Barbara"), V2.y = c(NA, 1252L,
445L, 134L, 254L), V982 = c(2L, 2L, 0L, 0L, 0L), V2163 = c(2L,
0L, 0L, 0L, 0L)), .Names = c("V3", "V1.x", "V2.x", "V1.y",
"V2.y", "V982", "V2163"), class = "data.frame", row.names = c("1",
"2", "3", "4", "5"))
d1 <- df1[df1$V3 %in% df2$V3,]
d2 <- df2[df2$V3 %in% df1$V3,]
m <- match(d2$V3,d1$V3)
z <- sapply(names(d1),function(s) ifelse(is.na(d1[,s]),d2[m,s],d1[,s]))
result <- cbind(z,d2[m,setdiff(names(d2),names(d1)),drop=F])
df$V1 <- with(df,ifelse(is.na(V1.x),V1.y,V1.x))