2013-08-27 6 views
23

Mam ramkę danych z liczbą kolumn i chcę wypisać oddzielną kolumnę dla każdej z długości każdego wiersza w niej.Przechodzenie między kolumnami i dodawanie długości łańcuchów jako nowych kolumn

Próbuję iterować po nazwach kolumn, a dla każdej kolumny wyświetla się odpowiednia kolumna z dołączoną wartością "_length".

Na przykład col1 | col2 przejdzie do col1 | col2 | col1_length | col2_length

Kod używam jest:

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) 
} 

Jednak to rzuca i błąd: nieprawidłowa funkcja w skomplikowanym zadaniem. Czy mogę używać pętli w ten sposób w R?

Odpowiedz

60

Należy użyć [[, programowego odpowiednika $. W przeciwnym razie, na przykład, gdy i jest col1, R będzie szukało df$i zamiast df$col1.

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

Czy można to zrobić za pomocą którejkolwiek z funkcji apply? Myślę coś w stylu: 'junk <- sapply (names (df), function (x) df [[x]] <- str_length (df [[i]])) 'ale nie działa zgodnie z oczekiwaniami. –

8

Można użyć lapply przejść każdy kolumnę str_length, następnie cbind go do swojego pierwotnego 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

Z dplyr i stringr można użyć 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

Dla zachowania kompletności istnieje również rozwiązanie 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 
Powiązane problemy