Создание рядов роста в R

#r

Вопрос:

Рассмотрим набор данных Loblolly в массовом пакете.

 head(Loblolly)
    height age Seed
1    4.51   3  301
15  10.89   5  301
29  28.72  10  301
43  41.74  15  301
57  52.70  20  301
71  60.92  25  301
 

Для каждого семени я хотел бы создать новые переменные height1, age1 и height2,возраст 2. Результат будет примерно таким…

 height1 age1 height2 age2 Seed
4.51      3    10.89    5  301
10.89     5    28.72   10  301
28.72    10    41.74   15  301
 

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

Комментарии:

1. Попробуй Loblolly %>% group_by(Seed) %>% transmute(height1 = height, age1 = age, height2 = c(tail(height,-1),NA), age2 = c(tail(age,-1),NA)) %>% ungroup с dplyr пакетом.

2. Это работает. Это создает окончательное наблюдение для каждого семени, которое включает NAs, но которое можно легко удалить.

3. Loblolly %>% group_by(Seed) %>% transmute(height1 = height, age1 = age, height2 = c(tail(height,-1),NA), age2 = c(tail(age,-1),NA)) %>% dplyr::filter(!is.na(age2)) %>% ungroup() следует вынуть строки с. NAs

4. да, идеально… Я совсем забыл о «хвосте».

5. Я рад, что это было полезно.

Ответ №1:

Если я правильно понимаю ваш вопрос, вы должны быть в состоянии сделать что-то подобное:

 # get data frame length
n <- dim(Loblolly)[1]

df <- NULL

# combine appropriate vectors
df$height1 <- Loblolly$height[1:(n-1)]
df$age1    <- Loblolly$age[1:(n-1)]
df$height2 <- Loblolly$height[2:n]
df$age2    <- Loblolly$age[2:n]
df$Seed    <- Loblolly$Seed[1:(n-1)]

# flatten list as data.frame
head(data.frame(df))
 

Комментарии:

1. Да, это правильная идея. Однако с помощью этого кода последнее наблюдение одного семени сопряжено с первым наблюдением следующего семени. Но, возможно, с помощью оператора group_by в dplyr это сработало бы

Ответ №2:

Вот базовый метод R, который даст «зацепку» каждого наблюдения по семенам.

 myList <- split(Loblolly, Loblolly$Seed)
myList <- lapply(myList, function(x) setNames(cbind(head(x, -1), tail(x, -1)),
                                   paste0(names(Loblolly), rep(1:2, each=length(Loblolly)))))

dfNew <- do.call("rbind", myList)
 

Образец возвращенных данных представляет собой

 head(dfNew, 10)
       height1 age1 Seed1 height2 age2 Seed2
329.13    3.93    3   329    9.34    5   329
329.27    9.34    5   329   26.08   10   329
329.41   26.08   10   329   37.79   15   329
329.55   37.79   15   329   48.31   20   329
329.69   48.31   20   329   56.43   25   329
327.12    4.12    3   327    9.92    5   327
327.26    9.92    5   327   26.54   10   327
327.40   26.54   10   327   37.82   15   327
327.54   37.82   15   327   48.43   20   327
327.68   48.43   20   327   56.81   25   327