我有list
个data.frame
(在此示例中只有2个):
set.seed(1)
df1 <- data.frame(id = sample(LETTERS,50,replace=T), val = rnorm(50), val1 = rnorm(50), stringsAsFactors = F)
df2 <- data.frame(id = sample(LETTERS,30,replace=T), val = rnorm(30), val2 = rnorm(30), stringsAsFactors = F)
df.list <- list(df1,df2)
我只想通过共享列名的子集将join
data.frame
合并为一个id
。
如果我使用:
library(dplyr)
df <- df.list %>% purrr::reduce(dplyr::inner_join,by="id")
我没有加入的共享列名被x
和y
所修饰:
id val.x val1 val.y val2
1 G -0.05612874 0.2914462 2.087167 0.7876396
2 G -0.05612874 0.2914462 -0.255027 1.4411577
3 J -0.15579551 -0.4432919 -1.286301 1.0273924
实际上,对于我没有加入的共享列名,从列表中的单个data.frame中选择它们就足够了-不论它们存在于WRT中到加入的id
我不预先知道这些共享的列名,但这并不难发现:
例如:
df.list.colnames <- unlist(lapply(df.list,function(l) colnames(l %>% dplyr::select(-id))))
df.list.colnames <- table(df.list.colnames)
repeating.colnames <- names(df.list.colnames)[which(df.list.colnames > 1)]
然后允许我将它们与data.frame
中的list
分开:
repeating.colnames.df <- do.call(rbind,lapply(df.list,function(r) r %>% dplyr::select_(.dots = c("id",repeating.colnames)))) %>%
unique()
然后我可以加入data.frame
的列表,但这些列除外:
然后如上所述加入他们:
for(r in 1:length(df.list)) df.list[[r]] <- df.list[[r]] %>% dplyr::select_(.dots = paste0("-",repeating.colnames))
df <- df.list %>% purrr::reduce(dplyr::inner_join,by="id")
现在我要添加repeating.colnames.df
了。我不知道join
中的任何dplyr
不会返回df
和repeating.colnames.df
之间的所有组合,所以看来我只能做apply
在每个df$id
上,选择repeating.colnames.df
中的第一个匹配项,然后将结果与df
合并。
在这种情况下,还有什么麻烦的事吗?
答案 0 :(得分:2)
如果我没有正确遵循,我认为您可以通过编写一个自定义函数传递给reduce
来处理此问题,该函数标识公共列名(不包括您的联接列),并将这些列从“合并。在reduce
遍历列表时,该函数将“累积”唯一列,默认为“最左侧”表中的列。
类似这样的东西:
library(dplyr)
library(purrr)
set.seed(1)
df1 <- data.frame(id = sample(LETTERS,50,replace=T), val = rnorm(50), val1 = rnorm(50), stringsAsFactors = F)
df2 <- data.frame(id = sample(LETTERS,30,replace=T), val = rnorm(30), val2 = rnorm(30), stringsAsFactors = F)
df.list <- list(df1,df2)
fun <- function(df1, df2, by_col = "id"){
df1_names <- names(df1)
df2_names <- names(df2)
dup_cols <- intersect(df1_names[!df1_names %in% by_col], df2_names[!df2_names %in% by_col])
out <- dplyr::inner_join(df1, df2[, !(df2_names %in% dup_cols)], by = by_col)
return(out)
}
df_chase <- df.list %>% reduce(fun,by_col="id")
由reprex package(v0.2.1)于2019-01-15创建
如果将df_chase
与您的最终解决方案进行比较,则会得出相同的答案:
> all.equal(df_chase, df_orig)
[1] TRUE
答案 1 :(得分:0)
如果您说自己不太在乎它们,则可以使用 public static int removeLastTwoDigits(int n) {
int m = 0;
String sn = Integer.toString(m);
if(n>99 ) {
String result = sn.substring(0, sn.length() - 1);
m = Integer.parseInt(result);
}
return m;
}
:
base::merge