在列表中处理数据框:删除变量,添加新变量

4

定义一个包含两个数据框 df1df2 的列表 dats

dats <- list( df1 = data.frame(a=sample(1:3), b = sample(11:13)),
    df2 = data.frame(a=sample(1:3), b = sample(11:13)))

> dats
$df1
  a  b
1 2 12
2 3 11
3 1 13

$df2
  a  b
1 3 13
2 2 11
3 1 12

我希望在每个数据框中删除变量a。接下来,我想从外部数据框中添加一个变量,其包含每个数据框的id,如下所示:

ids <- data.frame(id=c("id1","id2"),df=c("df1","df2"))
> ids
  id  df
1 id1 df1
2 id2 df2

为了删除不必要的变量,我尝试了以下方法,但没有成功:

> dats <- lapply(dats, function(x) assign(x, x[,c("b")]))  
> Error in assign(x, x[, c("b")]) : invalid first argument

我不确定如何添加id。

我也尝试了更为恰当的方法:

> temp <- lapply(dats, function(x) subset(x[1], select=x[[1]]$b))
Error in x[[1]]$b : $ operator is invalid for atomic vectors

我发现令人困惑的是,str(out[1])返回一个列表,而str(out[[1]])返回一个数据框。我认为这可能与它有关。


如果您不同意我的编辑,请随意回滚。我喜欢这个问题。 - mechanical_meat
2个回答

5

或者尝试这样做:将ids提取到一个命名向量中,将数据框名称映射到id:

df2id <- ids$id
names(df2id) <- ids$df

> df2id
df1 df2 
id1 id2 
Levels: id1 id2

接下来使用mapply函数,将(a)删除每个数据框中的a列,同时(b)添加id列:

> mapply( function(d,x) cbind( subset(d, select = -a),
+                              id = x),
+         dats, df2id[ names(dats) ] ,
+         SIMPLIFY=FALSE)
$df1
   b  id
1 12 id1
2 11 id1
3 13 id1

$df2
   b  id
1 12 id2
2 11 id2
3 13 id2

请注意,我们将df2id[ names(dats) ]传递给mapply - 这样可以确保df2id中的数据框与dats中的数据框"对齐"。

2

这个可以吗?

dats <- list( df1 = data.frame(a=sample(1:3), b = sample(11:13)),
    df2 = data.frame(a=sample(1:3), b = sample(11:13)))

ids <- data.frame(id=c("id1","id2"),df=c("df1","df2"))

# remove variable a
dats2 <- lapply(dats, function(x) x[,!names(x) == "a"])

# add id
for(i in 1:length(dats2)) {
  dats2[[i]] <- merge(dats2[[i]], ids$id[ids$df == names(dats2)[i]])
}

dats2

  $df1
     x   y
  1 11 id1
  2 12 id1
  3 13 id1

  $df2
     x   y
  1 11 id2
  2 12 id2
  3 13 id2

非常简洁。在实际应用中,我试图对ids数据框进行排序,使其与dats2具有相同的顺序,然后循环遍历其中一个数据框。names(dats2)[i]在这里是一个启示。它允许使用merge并让r动态排序。 - Fred
有没有一种方法可以在同一行内指定追加的列的名称?我在我的应用程序中看到默认值是称为y。它可以指定为id吗? - Fred

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接