web-dev-qa-db-ja.com

列をループし、文字列の長さを新しい列として追加します

複数の列を持つデータフレームがあり、各行の長さを含む列を個別に出力したいと思います。

列名を反復処理しようとしています。各列の出力には、「_ 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でこのようにループを使用できますか?

29
Zfunk

プログラムで[[と同等の$を使用する必要があります。それ以外の場合、たとえば、icol1の場合、Rはdf$iではなくdf$col1を探します。

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

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
10
Simon O'Hanlon

dplyrおよび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
6
m0nhawk

完全を期すために、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
3
Uwe