2015-06-16 5 views
3

У меня есть большой кадр данных с столбцами, которые являются символьной строкой чисел, таких как «1, 2, 3, 4». Я хочу добавить новый столбец, который является средним из этих чисел. Я создал следующий пример:R: разделите строку на числовую и верните среднее значение в качестве нового столбца в фрейме данных

 set.seed(2015) 
    library(dplyr) 
    a<-c("1, 2, 3, 4", "2, 4, 6, 8", "3, 6, 9, 12") 
    df<-data.frame(a) 
    df$a <- as.character(df$a) 

Теперь я могу использовать strsplit разбить строку и возвращает среднее значение для данной строки, где [[1]] определяет первую строку.

mean(as.numeric(strsplit((df$a), split=", ")[[1]])) 
    [1] 2.5 

Проблема в том, когда я пытаюсь сделать это в кадре данных и ссылаться на номер строки, я получаю сообщение об ошибке.

> df2<- df %>% 
    + mutate(index = row_number(), 
    +   avg = mean(as.numeric(strsplit((df$a), split=", ") 
    [[index]]))) 
    Error in strsplit((df$a), split = ", ")[[1:3]] : 
     recursive indexing failed at level 2 

Может ли кто-нибудь объяснить эту ошибку и почему я не могу индексировать ее с помощью переменной? Если я заменю индекс константой, это работает, мне кажется, что я не использую переменную там.

Большое спасибо!

ответ

2

Вы можете использовать sapply цикл по списку возвращенного strsplit, обработка каждого из элементов списка:

sapply(strsplit((df$a), split=", "), function(x) mean(as.numeric(x))) 
# [1] 2.5 5.0 7.5 
4

Try:

library(dplyr) 
library(splitstackshape) 

df %>% 
    mutate(index = row_number()) %>% 
    cSplit("a", direction = "long") %>% 
    group_by(index) %>% 
    summarise(mean = mean(a)) 

Что дает:

#Source: local data table [3 x 2] 
# 
# index mean 
#1  1 2.5 
#2  2 5.0 
#3  3 7.5 

или согласно @ предложение Ананды:

> rowMeans(cSplit(df, "a"), na.rm = T) 
# [1] 2.5 5.0 7.5 

Если вы хотите сохранить результат в кадре данных вы могли бы do:

df %>% mutate(mean = rowMeans(cSplit(., "a"), na.rm = T)) 

Что дает:

#   a mean 
#1 1, 2, 3, 4 2.5 
#2 2, 4, 6, 8 5.0 
#3 3, 6, 9, 12 7.5 
2
library(data.table) 
cols <- paste0("a",1:4) 
setDT(df)[, (cols) := tstrsplit(a, ",", fixed=TRUE, type.convert=TRUE) 
     ][, .(Mean = rowMeans(.SD)), .SDcols = cols] 
    Mean 
1: 2.5 
2: 5.0 
3: 7.5 

В качестве альтернативы,

rowMeans(setDT(tstrsplit(df$a, ",", fixed=TRUE, type.convert=TRUE))) 
# [1] 2.5 5.0 7.5 

 Смежные вопросы

  • Нет связанных вопросов^_^