R Заполните вектор, сопоставив имена со значениями столбца df - PullRequest
0 голосов
/ 03 мая 2018

У меня есть именованный вектор, заполненный нулями

toy1<- rep(0, length(37:45))
names(toy1) <- 37:45

Я хочу заполнить вектор данными подсчета из кадра данных

size    count
37      1.181
38      0.421
39      0.054
40      0.005
41      0.031
42      0.582
45      0.024

Мне нужна помощь, чтобы найти способ сопоставить значение размера с именем вектора, а затем ввести соответствующее значение счетчика в эту векторную позицию

Ответы [ 3 ]

0 голосов
/ 03 мая 2018

Допустим, ваш фрейм данных df , тогда вы можете просто обновить записи в toy1 для записей, доступных в вашем фрейме данных:

toy1[as.character(df$size)]    <- df$count

Редактировать: чтобы проверить соответствие m перед обновлением записей. m - соответствующие индексы в столбце размер в столбце df :

m <- match(names(toy1), as.character(df$size))

Затем для индексов в toy1 , у которых есть совпадение, его можно обновить следующим образом:

toy1[which(!is.na(m))]    <- df$count[m[!is.na(m)]]

PS: Эффективным способом было бы определить toy1 как фрейм данных и выполнить внешнее объединение по столбцу size .

0 голосов
/ 03 мая 2018

Может быть так просто, как:

toy1[ as.character(dat$size) ] <- dat$count
toy1

#   37    38    39    40    41    42    43    44    45 
#1.181 0.421 0.054 0.005 0.031 0.582 0.000 0.000 0.024 

Индексация R для назначений может иметь символьные значения. Если вы только что попытались проиндексировать необработанный столбец:

toy1[ dat$size ] <- dat$count

Вы бы получили (как я изначально):

> toy1
   37    38    39    40    41    42    43    44    45                                                             
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA 

   NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA 1.181 0.421 

0.054 0.005 0.031 0.582    NA    NA 0.024 

Это произошло из-за того, что произошла числовая индексация и было установлено расширение длины вектора по умолчанию для размещения чисел до 45.

С версией кадра данных с номером, который не находился в диапазоне 37:45, я получил предупреждение от использования match с несоответствием 0, но я также получил ожидаемые результаты:

toy1[ match( as.character( dat$size), names(toy1) , nomatch=0) ] <- dat$count
#------------
Warning message:
In toy1[match(as.character(dat$size), names(toy1), nomatch = 0)] <- dat$count :
  number of items to replace is not a multiple of replacement length
> toy1
   37    38    39    40    41    42    43    44    45 
1.181 0.421 0.054 0.005 0.031 0.582 0.000 0.000 0.000 

Функция match является ядром функции merge, но это приложение будет намного быстрее, чем merge фреймов данных

0 голосов
/ 03 мая 2018

Во-первых, давайте загрузим данные.

toy1<- rep(0, length(37:45))
names(toy1) <- 37:45
df = read.table(text="37      1.181
38      0.421
39      0.054
40      0.005
41      0.031
42      0.582
45      0.024")
names(df) = c("size","count")

Теперь я представляю действительно ужасное решение. Мы обновляем toy1 только там, где имя toy1 отображается в df$size. Мы возвращаем df$count, получая индекс совпадения в df. Я использую sapply, чтобы получить вектор индекса обратно. Для обоих размеров мы ищем только места, где names(toy1) появляется в df$size.

toy1[names(toy1) %in% df$size] = df$count[sapply(names(toy1)[names(toy1) %in% df$size],function(x){which(x == df$size)})]

Но это не очень элегантно. Вместо этого вы можете превратить toy1 в data.frame.

toydf = data.frame(toy1 = toy1,name = names(toy1),stringsAsFactors = FALSE)

Теперь мы можем использовать merge для получения значений.

updated = merge(toydf,df,by.x = "name",by.y="size",all.x=T)

Возвращает data.frame с 3 столбцами. Затем вы можете извлечь из этого столбец count, заменить NA на 0, и все готово.

updated$count[is.na(updated$count)] = 0
updated$count
#> [1] 1.181 0.421 0.054 0.005 0.031 0.582 0.000 0.000 0.024
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...