Подстановка результатов расчета

Я искажаю данные, в частности, я открыл этот pdf-файл http://pubs.acs.org/doi/suppl/10.1021/ja105035r/suppl_file/ja105035r_si_001.pdf и извлек данные из таблицы s4,

    1a 1b 1a 1b
1 5.27 4.76 5.09 4.75
2 2.47 2.74 2.77 2.80
4 1.14 1.38 1.12 1.02
6 7.43 7.35 7.22-7.35a 7.25-7.36a
7 7.38 7.34 7.22-7.35a 7.25-7.36a
8 7.23 7.20 7.22-7.35a 7.25-7.36a
9(R) 4.16 3.89 4.12b 4.18b
9(S) 4.16 3.92 4.12b 4.18b
10 1.19 0.91 1.21 1.25

вставил в блокнот и сохранил как txt файл.

s4 <- read.table("s4.txt", header=TRUE, stringsAsFactors=FALSE)

дает,

   X1a  X1b      X1a.1      X1b.1
1 5.27 4.76       5.09       4.75
2 2.47 2.74       2.77       2.80
4 1.14 1.38       1.12       1.02
6 7.43 7.35 7.22-7.35a 7.25-7.36a
7 7.38 7.34 7.22-7.35a 7.25-7.36a
8 7.23 7.20 7.22-7.35a 7.25-7.36a

чтобы использовать данные, мне нужно изменить все это на числовое и удалить буквы, благодаря этой ссылке R regex gsub отдельные буквы и цифры Я могу использовать следующий код,

gsub("([[:alpha:]])","",s4[,3])

Я могу избавиться от посторонних букв.

Что я хочу сделать сейчас, и суть вопроса - изменить диапазоны,

"7.22-7.35" "7.22-7.35" "7.22-7.35"

своими средствами,

"7.29"

Могу ли я использовать gsub для этого? (или мне нужно будет разделить строку через дефис, объединить в вектор и вернуть среднее значение?).


person DarrenRhodes    schedule 15.12.2014    source источник


Ответы (4)


Вам нужно одно регулярное выражение в strsplit для этой задачи (удаление букв и разделение):

s4[] <- lapply(s4, function(x) {
  if (is.numeric(x)) x
  else sapply(strsplit(as.character(x), "-|[[:alpha:]]"), 
              function(y) mean(as.numeric(y)))
})

Результат:

> s4
   X1a  X1b X1a.1 X1b.1
1 5.27 4.76 5.090 4.750
2 2.47 2.74 2.770 2.800
4 1.14 1.38 1.120 1.020
6 7.43 7.35 7.285 7.305
7 7.38 7.34 7.285 7.305
8 7.23 7.20 7.285 7.305
person Sven Hohenstein    schedule 15.12.2014
comment
спасибо (и спасибо другим участникам) несколько полезных советов - person DarrenRhodes; 15.12.2014

Вот подход, который, кажется, работает прямо на примере данных:

df[] <- lapply(df, function(col){
  col <- gsub("([[:alpha:]])","", col)
  col <- ifelse(grepl("-", col), mean(as.numeric(unlist(strsplit(col[grepl("-", col)], "-")))), col)
  as.numeric(col)
})

> df
#   X1a  X1b X1a.1 X1b.1
#1 5.27 4.76 5.090 4.750
#2 2.47 2.74 2.770 2.800
#4 1.14 1.38 1.120 1.020
#6 7.43 7.35 7.285 7.305
#7 7.38 7.34 7.285 7.305
#8 7.23 7.20 7.285 7.305

Отказ от ответственности: это работает правильно, только если диапазоны в каждом столбце одинаковы (как в примере данных)

person talat    schedule 15.12.2014

что-то такое :

mean(as.numeric(unlist(strsplit("7.22-7.35","-"))))

должно работать (и соответствовать тому, что вы имели в виду, я думаю)

или вы можете сделать:

eval(parse(text=paste0("mean(c(",gsub("-",",","7.22-7.35"),"))")))

но я не уверен, что это проще...

Чтобы применить его к вектору:

vec<-c("7.22-7.35","7.22-7.35")

1st solution : sapply(vec, function(x) mean(as.numeric(unlist(strsplit(x,"-")))))
2nd solution : sapply(vec, function(x) eval(parse(text=paste0("mean(c(",gsub("-",",",x),"))"))))

В обоих случаях вы получите:

7.22-7.35 7.22-7.35 
    7.285     7.285 
person Cath    schedule 15.12.2014
comment
Я знаю, что вы можете использовать sapply... В любом случае, похоже, что у ОП все равно все диапазоны одинаковы - person David Arenburg; 15.12.2014

Также,

library(gsubfn)
indx <- !sapply(s4, is.numeric)
s4[indx] <- lapply(s4[indx], function(x) 
          sapply(strapply(x, '([0-9.]+)', ~as.numeric(x)), mean))

s4
#   X1a  X1b X1a.1 X1b.1
#1 5.27 4.76 5.090 4.750
#2 2.47 2.74 2.770 2.800
#4 1.14 1.38 1.120 1.020
#6 7.43 7.35 7.285 7.305
#7 7.38 7.34 7.285 7.305
#8 7.23 7.20 7.285 7.305
person akrun    schedule 15.12.2014