2013-08-27 40 views
23

我有一个数据框,其中包含多个列,并且希望为每个列输出一个单独的列,并且每个列都包含每行的长度。循环遍历列并将字符串长度添加为新列

我想遍历列名,并为每个列输出一个相应的列'_length'附加。

例如col1 | col2会去col1 | col2 | col1_length | col2_length

我使用的代码是:

df <- data.frame(col1 = c("abc","abcd","a","abcdefg"),col2 = c("adf qqwe","d","e","f")) 

for(i in names(df)){ 
    df$paste(i,'length',sep="_") <- str_length(df$i) 
} 

然而,这将引发和错误:在复杂的转让无效的功能。我能在R中以这种方式使用循环吗?

回答

60

您需要使用[[,其编程等效为$。否则,例如,当icol1时,R将查找df$i而不是df$col1

for(i in names(df)){ 
    df[[paste(i, 'length', sep="_")]] <- str_length(df[[i]]) 
} 
+0

这可以使用任何应用函数来完成吗?我在想这样的:'junk < - sapply(names(df),function(x)df [[x]] < - str_length(df [[i]]))'但它不能按预期工作。 –

8

您可以使用lapply到每一列它传递给str_length,然后cbind你原来的data.frame ...

library(stringr) 

out <- lapply(df , str_length)  
df <- cbind(df , out) 

#  col1  col2 col1 col2 
#1  abc adf qqwe 3 8 
#2 abcd  d 4 1 
#3  a  e 1 1 
#4 abcdefg  f 7 1 
5

随着dplyrstringr您可以使用mutate_all

> df %>% mutate_all(funs(length = str_length(.))) 

    col1  col2 col1_length col2_length 
1  abc adf qqwe   3   8 
2 abcd  d   4   1 
3  a  e   1   1 
4 abcdefg  f   7   1 
2

为了完整起见,还有一个data.table解决方案:

library(data.table) 
result <- setDT(df)[, paste0(names(df), "_length") := lapply(.SD, stringr::str_length)] 
result 
#  col1  col2 col1_length col2_length 
#1:  abc adf qqwe   3   8 
#2: abcd  d   4   1 
#3:  a  e   1   1 
#4: abcdefg  f   7   1