我试图跟上R中的列表,并试图使列表中每个数据帧的每个奇数索引位置平方。请参见下面的可复制示例:
set.seed(100)
df <- data.frame(a = rnorm(5), b = rnorm(5))
oddsqr <- function(df){
(df[seq(1, nrow(df), 2), 2])^2 #selects odd index positions from column 2
}
如何编写for循环,以使每个奇数索引位置的平方值都替换现有值?我尝试了下面的解决方案,但失败了,因为我试图用长度为3的向量而不是长度为5的向量替换data.frame中的现有行。
for (i in seq_along(list.df)){
list.df[[i]][[2]][i] <- oddsqr(list.df[[i]])
}
解决方案
基于上面的示例,我已经弄清楚了如何获得答案,但是它看起来非常难以理解。如果有人可以帮助我优化它,将不胜感激:
for (k in seq_along(list.df)){
for (i in seq_along(list.df)){
list.df[[k]][[2]][vec[i]] <- oddsqr(list.df[[k]])[i]
}
}
解决方案2
基于以下Markus的解决方案:在这种情况下,可以使用lapply使一切变得更加干净和快捷!
答案 0 :(得分:1)
考虑lapply
out <- lapply(list.df, function(x) {
idx <- seq(1, nrow(x), 2)
x[idx, 2] <- x[idx, 2] ^ 2
x
})
结果
out
#$df1
# a b
#1 1 1
#2 2 2
#3 3 9
#4 4 4
#5 5 25
#$df2
# a b
#1 1 1
#2 2 2
#3 3 9
#4 4 4
#5 5 25
使用for
循环并稍微修改一下OP函数,我们可以获得相同的结果
# returns modified dataframe now and not a vector
oddsqr <- function(df){
df[seq(1, nrow(df), 2), 2] <- df[seq(1, nrow(df), 2), 2]^2 #selects odd index positions from column 2
df
}
for (i in seq_along(list.df)) {
list.df[[i]] <- oddsqr(list.df[[i]])
}
list.df
数据
df <- data.frame(a = 1:5, b = 1:5)
list.df <- list(df1 = df, df2 = df)
答案 1 :(得分:0)
这是tidyverse
library(tidyverse)
map(list.df, ~ .x %>%
mutate(b = case_when(row_number() %% 2 == 1 ~ b^2,
TRUE ~ as.numeric(b))))
df <- data.frame(a = 1:5, b = 1:5)
list.df <- list(df1 = df, df2 = df)