如何在列中的每个行字符串之前添加变量(列)名称

时间:2014-08-13 11:46:02

标签: r paste

我想将列名添加到列中的每个字符串。这是一个要使用的小数据框。

df <-structure(list(CoA = c("Baton Rouge", "Birmingham", "Chattanooga", 
"Columbia", "Houston"), CoB = c("Haddonfield, NJ", "Haddonfield, NJ", 
"Philadelphia, PA", "Hackensack, NJ", "Princeton, NJ"), CoC = c("St. Louis, Missouri", 
"Kansas City, Missouri", "Jefferson City, Missouri", "Belleville, Illinois", 
"Overland Park, Kansas")), .Names = c("CoA", "CoB", "CoC"), row.names = c(NA, 
-5L), class = "data.frame")

我尝试了以下内容,但是R通过对象公司和对象df进行了回收。

company <- colnames(df)
new <- sapply(df, function(x) paste(company, x, sep = ", ")) 

这就是我想要的,但对于所有列:

paste(colnames(df[1]), df$CoA, sep = ", ")
[1] "CoA, Baton Rouge" "CoA, Birmingham"  "CoA, Chattanooga" "CoA, Columbia"    "CoA, Houston"

我尝试了各种正则表达式而无处可去。如何让sapply对每个列执行此粘贴操作?

感谢您的帮助。

1 个答案:

答案 0 :(得分:4)

这是一个可能的解决方案:

mx <- sapply(colnames(df),function(name){ paste(name,df[,name],sep=", ")})

> mx
     CoA                CoB                     CoC                            
[1,] "CoA, Baton Rouge" "CoB, Haddonfield, NJ"  "CoC, St. Louis, Missouri"     
[2,] "CoA, Birmingham"  "CoB, Haddonfield, NJ"  "CoC, Kansas City, Missouri"   
[3,] "CoA, Chattanooga" "CoB, Philadelphia, PA" "CoC, Jefferson City, Missouri"
[4,] "CoA, Columbia"    "CoB, Hackensack, NJ"   "CoC, Belleville, Illinois"    
[5,] "CoA, Houston"     "CoB, Princeton, NJ"    "CoC, Overland Park, Kansas"

请注意sapply返回一个矩阵;如果您想要data.frame,只需执行as.data.frame(mx)

<强>解释

sapply将函数应用于第一个参数X中传递的向量/列表的每个元素(在这种情况下,我们传递colnames(df))。
应用于每个元素的函数通过参数FUN传递 在这种情况下,我们将以下函数传递给FUN

function(name){ 
   paste(name,df[,name],sep=", ")
   # equivalent to return(paste(name,df[,name],sep=", "))
}

colname(df)的每个元素调用此函数,并将每个元素作为第一个参数传递(即参数name)。
因此,使用name(记住是一个列名称)我们选择df列,我们使用paste函数添加列名称,然后返回生成的字符串向量。
剩下的部分留给sapply函数,它自动将每个结果向量绑定到一个矩阵中(因为默认为simplify=TRUE,否则将使用lapply)返回向量列表< / p>

编辑

正如@hadley正确指出的那样,sapplysimplify=TRUE的结果并不总是相同(例如,如果你只有一行或一列,它会改变)。
所以这是一个更安全的解决方案:

df2 <- as.data.frame(sapply(colnames(df),
                            function(name){ paste(name,df[,name],sep=", ")},
                            simplify=F))

> df2
               CoA                   CoB                           CoC
1 CoA, Baton Rouge  CoB, Haddonfield, NJ      CoC, St. Louis, Missouri
2  CoA, Birmingham  CoB, Haddonfield, NJ    CoC, Kansas City, Missouri
3 CoA, Chattanooga CoB, Philadelphia, PA CoC, Jefferson City, Missouri
4    CoA, Columbia   CoB, Hackensack, NJ     CoC, Belleville, Illinois
5     CoA, Houston    CoB, Princeton, NJ    CoC, Overland Park, Kansas