Извлечение и использование информации из других строк в кадре данных? - PullRequest
0 голосов
/ 22 ноября 2018

Итак, у меня есть фрейм данных, подобный следующему:

id age  friend1 friend2
01  15   02      05    
02  23   01      05    
03  51   04            
04  41   03            
05  33   01      02   

Как я могу рассчитать средний возраст друзей и создать новый столбец, в котором хранится эта информация?В идеале это выглядит примерно так:

id age  friend1 friend2 AvgAgeF
01  15   02      05        28
02  23   01      05        24
03  51   04                41
04  41   03                51
05  33   01      02        19  

В настоящее время я могу запустить следующий код, чтобы сделать это:

inx <- grep("friend", names(dat))
tmp <- sapply(inx, function(i) dat$age[dat[[i]]])
dat$AvgAgeF <- rowMeans(tmp, na.rm = TRUE)

Однако, когда «id» для людей непо порядку или вообще не являются числами, как, например, в следующем примере:

dat <- read.table(text = "
id    age  friend1 friend2
Bob   15   Jack    Sam    
Jack  23   Sam     Bob   
Sam   51   Bob     Jack     
Sara  41   Henry   NA       
Henry 33   Sara    NA                   
", header = TRUE)

Похоже, что код обрабатывается некорректно, что приводит к следующей таблице (Все, кроме AvgAgeF Сэма в этом случае неверны):

     id age friend1 friend2 AvgAgeF
1   Bob  15    Jack     Sam      51
2  Jack  23     Sam     Bob      28
3   Sam  51     Bob    Jack      19
4  Sara  41   Henry    <NA>      23
5 Henry  33    Sara    <NA>      33

Как я могу решить это, не меняя Имена в числовые идентификаторы.

1 Ответ

0 голосов
/ 22 ноября 2018

Подмножество столбцов age с friend1 и friend2 в качестве индексов, затем cbind результирующие векторы.Теперь это простой вызов rowMeans.

tmp <- with(dat, cbind(age[friend1], age[friend2]))
dat$AvgAgeF <- rowMeans(tmp, na.rm = TRUE)
rm(tmp)

dat
#  id age friend1 friend2 AvgAgeF
#1  1  15       2       5      28
#2  2  23       1       5      24
#3  3  51       4      NA      41
#4  4  41       3      NA      51
#5  5  33       1       2      19

Edit.

Если существует неопределенное количество столбцов friend*, необходимо следовать другой стратегии.
Первый набор данных, начиная с данных вопроса.

set.seed(1234)

tmp <- matrix(sample(c(NA, 1:5), 20, TRUE), nrow = 5)
colnames(tmp) <- paste0("friend", 3:6)
dat <- cbind(dat, tmp)

Теперь используйте grep, чтобы получить столбцы friend.

inx <- grep("friend", names(dat))
tmp <- sapply(inx, function(i) dat$age[dat[[i]]])
dat$AvgAgeF <- rowMeans(tmp, na.rm = TRUE)

Окончательная очистка.

rm(tmp)

Редактировать 2 - id являются символьными строками.

Если столбцы id и friend* являются символьными строками вместо числовых, индексный столбец age с match.

inx <- grep("friend", names(dat2))
tmp <- sapply(inx, function(i) {
  x <- as.character(dat2[[i]])
  y <- as.character(dat2$id)
  dat2$age[match(x, y)]
  })
dat2$AvgAgeF <- rowMeans(tmp, na.rm = TRUE)
rm(tmp)

dat2
#     id age friend1 friend2 AvgAgeF
#1   Bob  15    Jack     Sam      37
#2  Jack  23     Sam     Bob      33
#3   Sam  51     Bob    Jack      19
#4  Sara  41   Henry    <NA>      33
#5 Henry  33    Sara    <NA>      41

Данные.

dat <- read.table(text = "
id age  friend1 friend2
01  15   02      05    
02  23   01      05    
03  51   04     NA       
04  41   03     NA       
05  33   01      02                    
", header = TRUE)

dat2 <- read.table(text = "
id    age  friend1 friend2
Bob   15   Jack    Sam    
Jack  23   Sam     Bob   
Sam   51   Bob     Jack     
Sara  41   Henry   NA       
Henry 33   Sara    NA                   
", header = TRUE)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...