2013-08-27 10 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$col1の代わりにdf$iを検索します。

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

これは、適用機能のいずれかを使用して行うことができますか?私は次のようなものを考えていますか? [[i]])) '期待通りに動作しません。 –

8

あなたはそれがdplyrであなたの元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

cbind、その後、str_lengthに各列を渡すためにlapplyを使用することができますし、stringrあなたは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