简体   繁体   English

将列名粘贴到 R 中数据框的每个值

[英]Pasting the column name to each value of a dataframe in R

Hoping this isn't a repeat- I've had a search around but can't find quite what I'm looking for.希望这不是重复 - 我已经搜索过,但找不到我正在寻找的东西。

I have a dataframe (df) in R我在 R 中有一个数据框(df)

  1 2 3 4 5 
1 1 0.5 0.5 0 1
2 0.5 0.5 0.5 0 1
3 1 1 0 0 1
4 1 1 0 0 1 
5 1 1 0 0 1

(with the 1-5 indicating row and column names) (1-5表示行列名)

I would like to paste the column name to each cell, separated by a ":" so that it looks like this:我想将列名粘贴到每个单元格中,用“:”分隔,使其看起来像这样:

  1 2 3 4 5 
1 1:1 2:0.5 3:0.5 4:0 5:1 
2 1:0.5 2:0.5 3:0.5 4:0 5:1 
3 1:1 2:1 3:0 4:0 5:1 
4 1:1 2:1 3:0 4:0 5:1 
5 1:1 2:1 3:0 4:0 5:1 

However, my actual data is quite a bit larger.但是,我的实际数据要大一些。

I currently have我目前有

apply(df, 2, function(x) paste(colnames(df)[x], x, sep=":"))

Of course this doesn't work as colnames(df)[x] doesn't make any sense.当然,这不起作用,因为 colnames(df)[x] 没有任何意义。 Is there anything I can put in that first 'paste' term to get this sorted?有什么我可以在第一个“粘贴”术语中放入的东西来排序吗? Or another function to do a better job?或者其他功能可以做得更好?

Thanks.谢谢。

To explain my comment, Map is a multivariate version of lapply , so为了解释我的评论, Maplapply的多元版本,所以

df <- data.frame(`1` = c(1, 0.5, 1, 1, 1), 
                 `2` = c(0.5, 0.5, 1, 1, 1), 
                 `3` = c(0.5, 0.5, 0, 0, 0), 
                 `4` = c(0L, 0L, 0L, 0L, 0L), 
                 `5` = c(1L, 1L, 1L, 1L, 1L), 
                 check.names = FALSE)

df[] <- Map(paste, names(df), df, sep = ':')

df
##       1     2     3   4   5
## 1   1:1 2:0.5 3:0.5 4:0 5:1
## 2 1:0.5 2:0.5 3:0.5 4:0 5:1
## 3   1:1   2:1   3:0 4:0 5:1
## 4   1:1   2:1   3:0 4:0 5:1
## 5   1:1   2:1   3:0 4:0 5:1

Here Map takes the first element of names(df) , ie 1 , and paste s it to the first element of df , ie the first column.这里Map获取names(df)的第一个元素,即1 ,并将其pastedf的第一个元素,即第一列。 Assigning to df[] keeps the list's data.frame class, and therefore the original structure.分配给df[]保留列表的 data.frame 类,因此保留原始结构。

If your data is a matrix, you can do the same thing with sweep :如果你的数据是一个矩阵,你可以用sweep做同样的事情:

mat <- matrix(c(1, 0.5, 1, 1, 1, 0.5, 0.5, 1, 1, 1, 0.5, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1), 
              5, 5, 
              dimnames = list(c("1", "2", "3", "4", "5"), 
                              c("1", "2", "3", "4", "5")))

mat[] <- sweep(mat, 2, colnames(df), function(x, y) paste(y, x, sep = ':'))

mat
##   1       2       3       4     5    
## 1 "1:1"   "2:0.5" "3:0.5" "4:0" "5:1"
## 2 "1:0.5" "2:0.5" "3:0.5" "4:0" "5:1"
## 3 "1:1"   "2:1"   "3:0"   "4:0" "5:1"
## 4 "1:1"   "2:1"   "3:0"   "4:0" "5:1"
## 5 "1:1"   "2:1"   "3:0"   "4:0" "5:1"

As an alternative to looping, you can use col(., as.factor = TRUE) to create a matrix of column names, then paste it to the data (coerced to matrix).作为循环的替代方法,您可以使用col(., as.factor = TRUE)创建列名矩阵,然后将其粘贴到数据(强制转换为矩阵)。

df[] <- paste(col(df, TRUE), as.matrix(df), sep = ":")

Resulting in:导致:

 1 2 3 4 5 1 1:1 2:0.5 3:0.5 4:0 5:1 2 1:0.5 2:0.5 3:0.5 4:0 5:1 3 1:1 2:1 3:0 4:0 5:1 4 1:1 2:1 3:0 4:0 5:1 5 1:1 2:1 3:0 4:0 5:1

Actually, with these particular column names, as.factor = TRUE is not necessary.实际上,对于这些特定的列名称, as.factor = TRUE But it would be necessary for column names not the same as the column numbers.但是列名与列号不同是必要的。 For this particular example, it could be对于这个特定的例子,它可能是

df[] <- paste(col(df), as.matrix(df), sep = ":")

PS You should really be using a matrix with 100% numeric data, instead of a data frame. PS 您确实应该使用具有 100% 数字数据的矩阵,而不是数据框。

Data:数据:

df <- structure(list(`1` = c(1, 0.5, 1, 1, 1), `2` = c(0.5, 0.5, 1, 
1, 1), `3` = c(0.5, 0.5, 0, 0, 0), `4` = c(0L, 0L, 0L, 0L, 0L
), `5` = c(1L, 1L, 1L, 1L, 1L)), .Names = c("1", "2", "3", "4", 
"5"), class = "data.frame", row.names = c("1", "2", "3", "4", 
"5"))

We can unlist the dataset and paste with replicated elements of the column name我们可以unlist数据集并paste列名称的复制元素

df[] <- paste(names(df)[col(df)], unlist(df), sep=":")
df
#      1     2     3   4   5
#1   1:1 2:0.5 3:0.5 4:0 5:1
#2 1:0.5 2:0.5 3:0.5 4:0 5:1
#3   1:1   2:1   3:0 4:0 5:1
#4   1:1   2:1   3:0 4:0 5:1
#5   1:1   2:1   3:0 4:0 5:1

data数据

df <- structure(list(`1` = c(1, 0.5, 1, 1, 1), `2` = c(0.5, 0.5, 1, 
1, 1), `3` = c(0.5, 0.5, 0, 0, 0), `4` = c(0L, 0L, 0L, 0L, 0L
), `5` = c(1L, 1L, 1L, 1L, 1L)), .Names = c("1", "2", "3", "4", 
 "5"), class = "data.frame", row.names = c("1", "2", "3", "4", 
 "5"))

To update this for tidyverse, you can now run要为 tidyverse 更新此内容,您现在可以运行

df <- map2_dfc(colnames(df), df, paste, sep = ':')

map2 takes 2 inputs for the paste function, and the _dfc tag returns a dataframe as your result instead of a list. map2为 paste 函数接受 2 个输入, _dfc标签返回一个数据帧作为结果而不是列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM