Как запустить цикл for через список в кадре данных в R - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть фрейм данных, который содержит списки в каждой ячейке столбца фрейма данных. Например, вот тестовый фрейм данных.

df <- data.frame(id=1:2)
df$month <-  list(c("1","2","3"), c("3","5","7"))
df

Я хочу вычислить средние различия внутри каждого списка в строке и сохранить результаты в виде новой переменной, скажем, MeanDiff. Например. (1,2,3) имеет среднюю разницу 1 (((2-1) + (3-2)) / 2).

Мой цикл за пределами будет

for (i in 1: nrow(df)){
}

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

Diff = []
Diff[i] = i+1 - i
MeanDiff[i] = Diff/length(Diff)

Любая помощь будет принята с благодарностью! Кроме того, это мой первый пост в StackOverflow, я также буду благодарен за любые мета-отзывы о вопросах!

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

Вот два решения:

df$diff <- lapply(df$month, function(a) sum(diff(as.numeric(a)))/2)
df
#   id   month diff
# 1  1 1, 2, 3    1
# 2  2 3, 5, 7    2

Одна загвоздка в том, что, хотя она выглядит как обычный столбец, это не совсем то, что вы могли ожидать:

df$diff[1]
# [[1]]
# [1] 1

Это list одного элемента, где вы можете ожидать скаляр (или вектор длины 1, в случае R). Альтернативой (как предложил JilberUrbina) является использование sapply в тех случаях, когда вы ожидаете, что результат будет иметь длину 1:

df$diff2 <- sapply(df$month, function(a) sum(diff(as.numeric(a)))/2)
df$diff2[1]
# [1] 1

Если вы иначе используете набор инструментов tidyverse (который многие рекомендуют), попробуйте следующее:

library(dplyr)
library(purrr)

df %>%
  mutate(
    diff = map(month, ~ sum(diff(as.numeric(.)))/2)
  )
#   id   month diff
# 1  1 1, 2, 3    1
# 2  2 3, 5, 7    2

Если вы сохраните его в tibble по умолчанию *1019*, оно будет выглядеть так:

tbl_df(df) %>%
  mutate(
    diff = map(month, ~ sum(diff(as.numeric(.)))/2)
  )
# # A tibble: 2 x 3
#      id month     diff     
#   <int> <list>    <list>   
# 1     1 <chr [3]> <dbl [1]>
# 2     2 <chr [3]> <dbl [1]>

хотя это фактически одно и то же. Если вы планируете многократно хранить списки или другие сложные вещи в столбце (например, lm модель, predict ионы), то это может быть очень удобным и, возможно, в конечном итоге интуитивно понятным.

0 голосов
/ 06 сентября 2018

Вы можете использовать lapply

> lapply(df$month, function(x) 
    {tmp <- as.numeric(x)  # this converts character to numeric
    tmp <- sum(diff(tmp))/(length(tmp)-1) # performs calculations
    tmp})  # returns output
[[1]]
[1] 1

[[2]]
[1] 2

или sapply, если хотите, чтобы выходные данные были вектором, а не списком.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...