0

我有三个数据框df1,,df2df3

df1
     Freq
Yes    10
No      2

df2 
     Freq
Yes     5
No      7

df2 
     Freq
Yes     5
No      7

我把它结合到df

df1 <- data.frame(Freq= c(10,2))
df2 <- data.frame(Freq= c(5,7))
df3 <- data.frame(Freq= c(9,3))
rownames(df1) <- c("Yes","No")
rownames(df2) <- c("Yes","No")
rownames(df3) <- c("Yes","No")

df <- data.frame(rbind(df1,df2,df3))
df
       Freq
Yes      10
No        2
Yes1      5
No1       7
Yes2      9
No2       3

现在,如果您看到df,只要找到重复的行名,它就会在其旁边粘贴一个索引。

如何删除重复名称的索引并保持原样?然后我将其更改为列名中的rownames(df)第一列。dfAnswer

 library(tibble)
 df <- rownames_to_column(df,"Answer")

   Answer   Freq
      Yes     10
       No      2
     Yes1      5
      No1      7
     Yes2      9
      No2      3

期望的结果

   Answer   Freq
      Yes     10
       No      2
      Yes      5
       No      7
      Yes      9
       No      3
4

2 回答 2

1

rownames_to_column虽然您可以通过正则表达式删除索引(请参阅上面的评论),但您可以通过调用before you来避免该问题rbindpurrr::map_df这样做非常容易,因为它是将lapply其结果简化为 data.frame 的版本。因此,

library(tidyverse)    # contains both tibble and purrr

list(df1, df2, df3) %>% map_df(rownames_to_column, 'Answer')

##   Answer Freq
## 1    Yes   10
## 2     No    2
## 3    Yes    5
## 4     No    7
## 5    Yes    9
## 6     No    3

您还可以使用 purrr 的缩写匿名函数语法:~rownames_to_column(.x, 'Answer')或更传统的语法:map_df(list(df1, df2, df3), function(x){rownames_to_column(x, 'Answer')}),所有这些都做同样的事情。

如果你想用基础 R 完成同样的事情,

do.call(rbind, lapply(list(df1, df2, df3), function(x){
    x$Answer <- rownames(x); 
    rownames(x) <- NULL; 
    x
}))

返回相同的东西。

如果您想为哪个行来自哪个 data.frame 添加一个标识符列,请map_df为此类列传递一个名称.id(类似于 in dplyr::bind_rows),就像rownames_to_column

list(one = df1, two = df2, three = df3) %>% map_df(rownames_to_column, "Answer", .id = "df")

##      df Answer Freq
## 1   one    Yes   10
## 2   one     No    2
## 3   two    Yes    5
## 4   two     No    7
## 5 three    Yes    9
## 6 three     No    3

如果您未在列表中提供名称,则.id获取默认值,即数字字符串。喜欢就转换。

于 2017-01-13T16:15:08.177 回答
0

我们可以做到这一点data.table

library(data.table)
rbindlist(lapply(mget(paste0("df", 1:3)),
        function(x) transform(x, Answer = row.names(x))[2:1]))
#   Answer Freq
#1:    Yes   10
#2:     No    2
#3:    Yes    5
#4:     No    7
#5:    Yes    9
#6:     No    3
于 2017-01-16T04:29:35.817 回答