我想为列表中的每个数据框添加数据框名称到列中的所有行。
虚拟数据:
test_df <- data.frame(x = 1:5, y = c("a","b","c","d","e"))
我想要最终得到的是:
x y ref
1 a test_df
2 b test_df
3 c test_df
4 d test_df
5 e test_df
原因是我稍后将对多个数据帧进行rbind,我希望能够过滤值来自哪个数据帧。我尝试了以下方法:
library(dplyr)
test <- function(df) {
df <- df %>%
mutate(ref = deparse(substitute(df)))
return(df)
}
但是这只会在每行中创建一个名为ref的列,其值为“df”。任何有关dplyr的建议都非常感谢。或者有没有办法在rbind-call中直接创建这个列?
答案 0 :(得分:3)
使用dplyr
,试试这个:
library(lazyeval)
test <- function(df) {
df <- df %>% mutate(ref = expr_label(df))
return(df)
}
test(test_df)
x y ref
1 a `test_df`
2 b `test_df`
3 c `test_df`
4 d `test_df`
5 e `test_df`
或者,这也有效,但不使用dplyr
:
test2 <- function(df) {
df$ref <- deparse(substitute(df))
return(df)
}
test2(test_df)
x y ref
1 1 a test_df
2 2 b test_df
3 3 c test_df
4 4 d test_df
5 5 e test_df
要使这项工作与数据框列表一致,而lapply
由于lapply
的工作原理而变得更加棘手,但以下解决方法有效:
test_df <- data.frame(x = 1:5, y = c("a","b","c","d","e"))
test_df2 <- data.frame(x = 11:15, y = c("aa","bb","cc","dd","ee"))
在这里,我创建了一个命名的数据帧列表:
dfs <- setNames(list(test_df, test_df2), c("test_df", "test_df2"))
dfs
$test_df
x y
1 1 a
2 2 b
3 3 c
4 4 d
5 5 e
$test_df2
x y
1 11 aa
2 12 bb
3 13 cc
4 14 dd
5 15 ee
现在我改变辅助函数以接受名称作为参数:
test3 <- function(df, nm) {
df$ref <- nm
return(df)
}
这里我只将名称传递给lapply
,并从我上面定义的命名列表dfs
中检索每个数据帧。
lapply(names(dfs), function(x) test3(dfs[[x]], x))
[[1]]
x y ref
1 1 a test_df
2 2 b test_df
3 3 c test_df
4 4 d test_df
5 5 e test_df
[[2]]
x y ref
1 11 aa test_df2
2 12 bb test_df2
3 13 cc test_df2
4 14 dd test_df2
5 15 ee test_df2
这不是最优雅的方式,但它有效。
话虽如此,如果您想将数据帧合并为一个数据帧,那么@ markus建议使用bind_rows
的内容并不多,如
bind_rows(dfs, .id="ref")
ref x y
1 test_df 1 a
2 test_df 2 b
3 test_df 3 c
4 test_df 4 d
5 test_df 5 e
6 test_df2 11 aa
7 test_df2 12 bb
8 test_df2 13 cc
9 test_df2 14 dd
10 test_df2 15 ee
答案 1 :(得分:1)
原因是我将在以后重新绑定多个数据帧 我希望能够过滤值来自哪个数据框。
然后只需将dplyr::bind_rows
与.id
参数一起使用:
library(dplyr)
bind_rows(df_list,.id="name")
# works also : purrr::map_dfr(df_list,identity,.id="name")
# works also : data.table::rbindlist(df_list,idcol="name")
# name x y
# 1 A 1 a
# 2 A 2 b
# 3 B 1 a
# 4 B 2 b
# 5 C 1 a
# 6 C 2 b
如果您的data.frames
已不在列表中,请注意tibble::lst
会在将这些元素添加到列表时对其进行命名,例如lst(df_A,df_B,df_C)
您的示例案例因此由bind_rows(lst(test_df),.id="name")
数据强>
test_df <- data.frame(x = 1:2, y = c("a","b"))
df_list <- setNames(replicate(3,test_df,FALSE),LETTERS[1:3])
# $A
# x y
# 1 1 a
# 2 2 b
#
# $B
# x y
# 1 1 a
# 2 2 b
#
# $C
# x y
# 1 1 a
# 2 2 b